Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ContinuousReheater.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ContinuousReheater.cs	(revision 14452)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ContinuousReheater.cs	(revision 14452)
@@ -0,0 +1,202 @@
+﻿using HeuristicLab.Operators;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    [Item("Continuous Reheater", "Reheats the temperature continuously, while the acceptance rate of solutions is under the threshold.")]
+    [StorableClass]
+    public class ContinuousReheater : SingleSuccessorOperator, ISimulatedAnnealingHeatingStrategy
+    {
+        #region Strings
+        private const string UpperTemperatureName = "UpperTemperature";
+        private const string ReheatingOperatorName = "ReheatingOperator";
+        private const string ThresholdName = "Threshold";
+        private const string MemorySizeName = "MemorySize";
+
+
+        private const string IterationsName = "Iterations";
+        private const string MaximumIterationsName = "MaximumIterations";
+        private const string TemperatureStartIndexName = "TemperatureStartIndex";
+        private const string StartTemperatureName = "StartTemperature";
+        private const string EndTemperatureName = "EndTemperature";
+        private const string TemperatureName = "Temperature";
+        private const string CoolingName = "Cooling";
+        private const string IsAcceptedName = "IsAccepted";
+        private const string AcceptanceMemoryName = "AcceptanceMemory";
+
+
+        #endregion
+        #region Parameters
+        private ValueParameter<DoubleValue> UpperTemperatureParameter
+        {
+            get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
+        }
+        private IConstrainedValueParameter<IDiscreteDoubleValueModifier> ReheatingOperatorParameter
+        {
+            get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[ReheatingOperatorName]; }
+        }
+        private ValueParameter<DoubleRange> ThresholdParameter
+        {
+            get { return (ValueParameter<DoubleRange>)Parameters[ThresholdName]; }
+        }
+        private ValueParameter<IntValue> MemorySizeParameter
+        {
+            get { return (ValueParameter<IntValue>)Parameters[MemorySizeName]; }
+        }
+
+        public ILookupParameter<IntValue> IterationsParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
+        }
+        public IValueLookupParameter<IntValue> MaximumIterationsParameter
+        {
+            get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
+        }
+        public ILookupParameter<DoubleValue> TemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
+        }
+        public ILookupParameter<DoubleValue> EndTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
+        }
+        public ILookupParameter<DoubleValue> StartTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
+        }
+        public ILookupParameter<IntValue> TemperatureStartIndexParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
+        }
+        public ILookupParameter<BoolValue> CoolingParameter
+        {
+            get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
+        }
+        public ILookupParameter<BoolValue> IsAcceptedParameter
+        {
+            get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
+        }
+        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
+        {
+            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
+        }
+
+        #endregion
+        #region Properties
+        public DoubleValue UpperTemperature
+        {
+            get { return UpperTemperatureParameter.Value; }
+            set { UpperTemperatureParameter.Value = value; }
+        }
+        public IDiscreteDoubleValueModifier ReheatingOperator
+        {
+            get { return ReheatingOperatorParameter.Value; }
+            set { ReheatingOperatorParameter.Value = value; }
+        }
+        public DoubleRange AcceptanceThreshold
+        {
+            get { return ThresholdParameter.Value; }
+            set { ThresholdParameter.Value = value; }
+        }
+        public IntValue AcceptanceMemorySize
+        {
+            get { return MemorySizeParameter.Value; }
+            set { MemorySizeParameter.Value = value; }
+        }
+        #endregion
+
+        public ContinuousReheater() : base()
+        {
+            #region Create parameters
+            Parameters.Add(new ValueParameter<DoubleValue>(UpperTemperatureName, "The upper bound of the temperature.", new DoubleValue(100d)));
+            Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>(ReheatingOperatorName, "Reheating operator."));
+            Parameters.Add(new ValueParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature. If the average ratio of accepted moves goes below the start of the range the temperature is heated. If the the average ratio of accepted moves goes beyond the end of the range the temperature is cooled again.", new DoubleRange(0.1, 0.05)));
+            Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(100)));
+
+            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
+            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
+            Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
+            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
+            Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
+            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
+            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
+            Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
+            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
+            #endregion
+
+            foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
+            {
+                ReheatingOperatorParameter.ValidValues.Add(op);
+            }
+
+            Parameterize();
+        }
+
+        [StorableConstructor]
+        protected ContinuousReheater(bool deserializing) : base(deserializing) { }
+        protected ContinuousReheater(ContinuousReheater original, Cloner cloner) : base(original, cloner) { }
+
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new ContinuousReheater(this, cloner);
+        }
+
+        public void Parameterize()
+        {
+            foreach (var op in ReheatingOperatorParameter.ValidValues)
+            {
+                op.IndexParameter.ActualName = IterationsName;
+                op.IndexParameter.Hidden = true;
+                op.StartIndexParameter.Value = null;
+                op.StartIndexParameter.ActualName = TemperatureStartIndexName;
+                op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
+                op.ValueParameter.ActualName = TemperatureName;
+                op.ValueParameter.Hidden = true;
+                op.StartValueParameter.ActualName = StartTemperatureName;
+                op.StartValueParameter.Hidden = true;
+                op.EndValueParameter.ActualName = EndTemperatureName;
+                op.EndValueParameter.Hidden = true;
+            }
+        }
+
+        public bool ShouldReheat(bool cooling, ItemList<BoolValue> acceptances) {
+
+            if (acceptances.Count > MemorySizeParameter.Value.Value) acceptances.RemoveAt(0);
+
+            var ratioStart = ThresholdParameter.Value.Start;
+            var ratioEnd = ThresholdParameter.Value.End;
+            var ratio = acceptances.Average(x => x.Value ? 1.0 : 0.0);
+            if (!cooling && ratio >= ratioEnd)
+            {
+                return false;
+            }
+            else if (cooling && ratio <= ratioStart)
+            {  // temperature is cooled, but should be heated
+                return true;
+            }
+            return !cooling;
+        }
+        public override IOperation Apply()
+        {
+            var iterations = IterationsParameter.ActualValue.Value;
+            TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, iterations - 1);
+            StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
+            EndTemperatureParameter.ActualValue.Value = UpperTemperatureParameter.Value.Value;
+
+            return new OperationCollection {
+                   ExecutionContext.CreateOperation(ReheatingOperatorParameter.Value), base.Apply()};
+        }
+    }
+}
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/FixedReheater.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/FixedReheater.cs	(revision 14452)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/FixedReheater.cs	(revision 14452)
@@ -0,0 +1,94 @@
+﻿using HeuristicLab.Operators;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    [Item("Fixed Reheater", "Increases temperature by a fixed amount, each time n consecutive solutions are not accepted.")]
+    [StorableClass]
+    public class FixedReheater : SingleSuccessorOperator, ISimulatedAnnealingHeatingStrategy
+    {
+        #region Strings
+        private const string AmountName = "Amount";
+        private const string ThresholdName = "Threshold";
+        private const string TemperatureName = "Temperature";
+        private const string AcceptanceMemoryName = "AcceptanceMemory";
+
+
+        #endregion
+        #region Parameters
+        private ValueParameter<DoubleValue> AmountParameter
+        {
+            get { return (ValueParameter<DoubleValue>)Parameters[AmountName]; }
+        }
+        private ValueParameter<IntValue> ThresholdParameter
+        {
+            get { return (ValueParameter<IntValue>)Parameters[ThresholdName]; }
+        }
+        public ILookupParameter<DoubleValue> TemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
+        }
+        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
+        {
+            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
+        }
+
+        #endregion
+        #region Properties
+        public DoubleValue Amount
+        {
+            get { return AmountParameter.Value; }
+            set { AmountParameter.Value = value; }
+        }
+        public IntValue AcceptanceThreshold
+        {
+            get { return ThresholdParameter.Value; }
+            set { ThresholdParameter.Value = value; }
+        }
+        #endregion
+
+        public FixedReheater() : base()
+        {
+            #region Create parameters
+            Parameters.Add(new ValueParameter<DoubleValue>(AmountName, "The amount the temperature gets increased with every reheat.", new DoubleValue(20d)));
+            Parameters.Add(new ValueParameter<IntValue>(ThresholdName, "Amount of consecutive rejected solutions that will trigger a reheat.", new IntValue(5)));
+            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
+            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
+            #endregion
+        }
+
+        [StorableConstructor]
+        protected FixedReheater(bool deserializing) : base(deserializing) { }
+        protected FixedReheater(FixedReheater original, Cloner cloner) : base(original, cloner) { }
+
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new FixedReheater(this, cloner);
+        }
+
+        public void Parameterize() { }
+
+        public bool ShouldReheat(bool cooling, ItemList<BoolValue> acceptances) {
+            if (acceptances.Count > ThresholdParameter.Value.Value) acceptances.RemoveAt(0);
+            return acceptances.Count == ThresholdParameter.Value.Value && !acceptances.Any(x => x.Value);
+        }
+        public override IOperation Apply()
+        {
+            AcceptanceMemoryParameter.ActualValue.Clear();
+            TemperatureParameter.ActualValue.Value += AmountParameter.Value.Value;
+            return base.Apply();
+        }
+    }
+}
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj	(revision 14406)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj	(revision 14452)
@@ -114,9 +114,13 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ISimulatedAnnealingHeatingStrategy.cs" />
     <Compile Include="Plugin.cs" />
+    <Compile Include="FixedReheater.cs" />
+    <Compile Include="ContinuousReheater.cs" />
     <Compile Include="SimulatedAnnealingImprovementOperator.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SimulatedAnnealing.cs" />
     <Compile Include="SimulatedAnnealingMainLoop.cs" />
+    <Compile Include="TemperatureController.cs" />
   </ItemGroup>
   <ItemGroup>
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ISimulatedAnnealingHeatingStrategy.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ISimulatedAnnealingHeatingStrategy.cs	(revision 14452)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/ISimulatedAnnealingHeatingStrategy.cs	(revision 14452)
@@ -0,0 +1,17 @@
+﻿using HeuristicLab.Core;
+using HeuristicLab.Data;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    public interface ISimulatedAnnealingHeatingStrategy : IOperator
+    {
+        void Parameterize();
+
+        bool ShouldReheat(bool currentCoolingState, ItemList<BoolValue> accepts);
+    }
+}
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 14406)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 14452)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Analysis;
@@ -35,466 +34,589 @@
 using HeuristicLab.Random;
 
-namespace HeuristicLab.Algorithms.SimulatedAnnealing {
-  [Item("Simulated Annealing (SA)", "A simulated annealing algorithm.")]
-  [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 140)]
-  [StorableClass]
-  public sealed class SimulatedAnnealing : HeuristicOptimizationEngineAlgorithm, IStorableContent {
-    public string Filename { get; set; }
-
-    #region Problem Properties
-    public override Type ProblemType {
-      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    [Item("Simulated Annealing", "An advanced simulated annealing algorithm.")]
+    [Creatable("Algorithms")]
+    [StorableClass]
+    public sealed class SimulatedAnnealing : HeuristicOptimizationEngineAlgorithm, IStorableContent
+    {
+        #region Strings
+        private const string SeedName = "Seed";
+        private const string SetSeedRandomlyName = "SetSeedRandomly";
+        private const string MoveGeneratorName = "MoveGenerator";
+        private const string MoveEvaluatorName = "MoveEvaluator";
+        private const string MoveMakerName = "MoveMaker";
+        private const string AnnealingOperatorName = "AnnealingOperator";
+        private const string HeatingStrategyOperatorName = "HeatingStrategyOperator";
+        private const string MaximumIterationsName = "MaximumIterations";
+        private const string InitialTemperatureName = "InitialTemperature";
+        private const string LowerTemperatureName = "LowerTemperature";
+        private const string AnalyzerName = "Analyzer";
+        private const string RandomName = "Random";
+        private const string EvaluatedMovesName = "EvaluatedMoves";
+        private const string IterationsName = "Iterations";
+        private const string TemperatureStartIndexName = "TemperatureStartIndex";
+        private const string CoolingName = "Cooling";
+        private const string StartTemperatureName = "StartTemperature";
+        private const string EndTemperatureName = "EndTemperature";
+        private const string TemperatureName = "Temperature";
+        private const string ResultsName = "Results";
+        private const string TemperatureChartName = "Temperature Chart";
+        private const string TemperatureAnalyzerName = "Temperature Analyzer";
+        #endregion
+
+        public string Filename { get; set; }
+
+        #region Problem Properties
+        public override Type ProblemType
+        {
+            get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
+        }
+        public new ISingleObjectiveHeuristicOptimizationProblem Problem
+        {
+            get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
+            set { base.Problem = value; }
+        }
+        #endregion
+
+        #region Parameter Properties
+        private ValueParameter<IntValue> SeedParameter
+        {
+            get { return (ValueParameter<IntValue>)Parameters[SeedName]; }
+        }
+        private ValueParameter<BoolValue> SetSeedRandomlyParameter
+        {
+            get { return (ValueParameter<BoolValue>)Parameters[SetSeedRandomlyName]; }
+        }
+        public IConstrainedValueParameter<IMultiMoveGenerator> MoveGeneratorParameter
+        {
+            get { return (IConstrainedValueParameter<IMultiMoveGenerator>)Parameters[MoveGeneratorName]; }
+        }
+        public IConstrainedValueParameter<IMoveMaker> MoveMakerParameter
+        {
+            get { return (IConstrainedValueParameter<IMoveMaker>)Parameters[MoveMakerName]; }
+        }
+        public IConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter
+        {
+            get { return (IConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters[MoveEvaluatorName]; }
+        }
+        public IConstrainedValueParameter<IDiscreteDoubleValueModifier> AnnealingOperatorParameter
+        {
+            get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[AnnealingOperatorName]; }
+        }
+        public OptionalConstrainedValueParameter<ISimulatedAnnealingHeatingStrategy> HeatingStrategyOperatorParameter
+        {
+            get { return (OptionalConstrainedValueParameter<ISimulatedAnnealingHeatingStrategy>)Parameters[HeatingStrategyOperatorName]; }
+        }
+
+        private ValueParameter<IntValue> MaximumIterationsParameter
+        {
+            get { return (ValueParameter<IntValue>)Parameters[MaximumIterationsName]; }
+        }
+        private ValueParameter<DoubleValue> InitialTemperatureParameter
+        {
+            get { return (ValueParameter<DoubleValue>)Parameters[InitialTemperatureName]; }
+        }
+        private ValueParameter<DoubleValue> LowerTemperatureParameter
+        {
+            get { return (ValueParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
+        }
+        private ValueParameter<MultiAnalyzer> AnalyzerParameter
+        {
+            get { return (ValueParameter<MultiAnalyzer>)Parameters[AnalyzerName]; }
+        }
+        #endregion
+
+        #region Properties
+        public IntValue Seed
+        {
+            get { return SeedParameter.Value; }
+            set { SeedParameter.Value = value; }
+        }
+        public BoolValue SetSeedRandomly
+        {
+            get { return SetSeedRandomlyParameter.Value; }
+            set { SetSeedRandomlyParameter.Value = value; }
+        }
+        public IMultiMoveGenerator MoveGenerator
+        {
+            get { return MoveGeneratorParameter.Value; }
+            set { MoveGeneratorParameter.Value = value; }
+        }
+        public IMoveMaker MoveMaker
+        {
+            get { return MoveMakerParameter.Value; }
+            set { MoveMakerParameter.Value = value; }
+        }
+        public ISingleObjectiveMoveEvaluator MoveEvaluator
+        {
+            get { return MoveEvaluatorParameter.Value; }
+            set { MoveEvaluatorParameter.Value = value; }
+        }
+        public IDiscreteDoubleValueModifier AnnealingOperator
+        {
+            get { return AnnealingOperatorParameter.Value; }
+            set { AnnealingOperatorParameter.Value = value; }
+        }
+        public ISimulatedAnnealingHeatingStrategy HeatingStrategyOperator
+        {
+            get { return HeatingStrategyOperatorParameter.Value; }
+            set { HeatingStrategyOperatorParameter.Value = value; }
+        }
+
+        public IntValue MaximumIterations
+        {
+            get { return MaximumIterationsParameter.Value; }
+            set { MaximumIterationsParameter.Value = value; }
+        }
+        public DoubleValue InitialTemperature
+        {
+            get { return InitialTemperatureParameter.Value; }
+            set { InitialTemperatureParameter.Value = value; }
+        }
+        public DoubleValue LowerTemperature
+        {
+            get { return LowerTemperatureParameter.Value; }
+            set { LowerTemperatureParameter.Value = value; }
+        }
+        public MultiAnalyzer Analyzer
+        {
+            get { return AnalyzerParameter.Value; }
+            set { AnalyzerParameter.Value = value; }
+        }
+        private RandomCreator RandomCreator
+        {
+            get { return (RandomCreator)OperatorGraph.InitialOperator; }
+        }
+        private SolutionsCreator SolutionsCreator
+        {
+            get { return (SolutionsCreator)RandomCreator.Successor; }
+        }
+        private SimulatedAnnealingMainLoop MainLoop
+        {
+            get { return OperatorGraph.Iterate().OfType<SimulatedAnnealingMainLoop>().First(); }
+        }
+        #endregion
+
+        [StorableConstructor]
+        private SimulatedAnnealing(bool deserializing) : base(deserializing) { }
+        private SimulatedAnnealing(SimulatedAnnealing original, Cloner cloner)
+          : base(original, cloner)
+        {
+            RegisterEventHandlers();
+        }
+        public SimulatedAnnealing()
+          : base()
+        {
+            Parameters.Add(new ValueParameter<IntValue>(SeedName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+            Parameters.Add(new ValueParameter<BoolValue>(SetSeedRandomlyName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+            Parameters.Add(new ConstrainedValueParameter<IMultiMoveGenerator>(MoveGeneratorName, "The operator used to generate moves to the neighborhood of the current solution."));
+            Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>(MoveEvaluatorName, "The operator used to evaluate a move."));
+            Parameters.Add(new ConstrainedValueParameter<IMoveMaker>(MoveMakerName, "The operator used to perform a move."));
+            Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>(AnnealingOperatorName, "The operator used to cool the temperature."));
+            Parameters.Add(new OptionalConstrainedValueParameter<ISimulatedAnnealingHeatingStrategy>(HeatingStrategyOperatorName, "1The operator used to heat the temperature."));
+            Parameters.Add(new ValueParameter<IntValue>(MaximumIterationsName, "The maximum number of generations which should be processed.", new IntValue(10000)));
+            Parameters.Add(new ValueParameter<DoubleValue>(InitialTemperatureName, "The initial temperature.", new DoubleValue(100)));
+            Parameters.Add(new ValueParameter<DoubleValue>(LowerTemperatureName, "The lower bound for the temperature.", new DoubleValue(1e-6)));
+            Parameters.Add(new ValueParameter<MultiAnalyzer>(AnalyzerName, "The operator used to analyze each iteration.", new MultiAnalyzer()));
+
+            var randomCreator = new RandomCreator();
+            var solutionsCreator = new SolutionsCreator();
+            var variableCreator = new VariableCreator();
+            var startTemperatureAssigner = new Assigner();
+            var endTemperatureAssigner = new Assigner();
+            var temperatureAssigner = new Assigner();
+            var resultsCollector = new ResultsCollector();
+            var mainLoop = new SimulatedAnnealingMainLoop();
+            OperatorGraph.InitialOperator = randomCreator;
+
+            randomCreator.RandomParameter.ActualName = RandomName;
+            randomCreator.SeedParameter.ActualName = SeedParameter.Name;
+            randomCreator.SeedParameter.Value = null;
+            randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
+            randomCreator.SetSeedRandomlyParameter.Value = null;
+            randomCreator.Successor = solutionsCreator;
+
+            solutionsCreator.NumberOfSolutions = new IntValue(1);
+            solutionsCreator.Successor = variableCreator;
+
+            variableCreator.Name = "Initialize Variables";
+            variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(EvaluatedMovesName, new IntValue()));
+            variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(IterationsName, new IntValue(0)));
+            variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(TemperatureStartIndexName, new IntValue(0)));
+            variableCreator.CollectedValues.Add(new ValueParameter<BoolValue>(CoolingName, new BoolValue(true)));
+            variableCreator.Successor = startTemperatureAssigner;
+
+            startTemperatureAssigner.Name = "Assign Start Temperature";
+            startTemperatureAssigner.LeftSideParameter.ActualName = StartTemperatureName;
+            startTemperatureAssigner.RightSideParameter.ActualName = InitialTemperatureParameter.Name;
+            startTemperatureAssigner.Successor = endTemperatureAssigner;
+
+            endTemperatureAssigner.Name = "Assign End Temperature";
+            endTemperatureAssigner.LeftSideParameter.ActualName = EndTemperatureName;
+            endTemperatureAssigner.RightSideParameter.ActualName = LowerTemperatureParameter.Name;
+            endTemperatureAssigner.Successor = temperatureAssigner;
+
+            temperatureAssigner.Name = "Initialize Temperature";
+            temperatureAssigner.LeftSideParameter.ActualName = TemperatureName;
+            temperatureAssigner.RightSideParameter.ActualName = StartTemperatureName;
+            temperatureAssigner.Successor = resultsCollector;
+
+            resultsCollector.CopyValue = new BoolValue(false);
+            resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>(EvaluatedMovesName, null));
+            resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>(IterationsName, null));
+            resultsCollector.ResultsParameter.ActualName = ResultsName;
+            resultsCollector.Successor = mainLoop;
+
+            mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+            mainLoop.AnnealingOperatorParameter.ActualName = AnnealingOperatorParameter.Name;
+            mainLoop.CoolingParameter.ActualName = CoolingName;
+            mainLoop.EndTemperatureParameter.ActualName = EndTemperatureName;
+            mainLoop.EvaluatedMovesParameter.ActualName = EvaluatedMovesName;
+            mainLoop.HeatingStrategyOperatorParameter.ActualName = HeatingStrategyOperatorParameter.Name;
+
+            mainLoop.IterationsParameter.ActualName = IterationsName;
+            mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+            mainLoop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
+            mainLoop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
+            mainLoop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
+            mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+            mainLoop.ResultsParameter.ActualName = ResultsName;
+            mainLoop.StartTemperatureParameter.ActualName = StartTemperatureName;
+            mainLoop.TemperatureStartIndexParameter.ActualName = TemperatureStartIndexName;
+            mainLoop.TemperatureParameter.ActualName = TemperatureName;
+
+            foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
+            {
+                AnnealingOperatorParameter.ValidValues.Add(op);
+            }
+
+            foreach (var op in ApplicationManager.Manager.GetInstances<ISimulatedAnnealingHeatingStrategy>().OrderBy(x => x.Name))
+            {
+                HeatingStrategyOperatorParameter.ValidValues.Add(op);
+            }
+
+            UpdateAnalyzers();
+
+            Parameterize();
+
+            RegisterEventHandlers();
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new SimulatedAnnealing(this, cloner);
+        }
+
+        [StorableHook(HookType.AfterDeserialization)]
+        private void AfterDeserialization()
+        {
+            RegisterEventHandlers();
+        }
+
+        private void RegisterEventHandlers()
+        {
+            if (Problem != null)
+            {
+                Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
+                foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>())
+                {
+                    op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
+                }
+            }
+            MoveGeneratorParameter.ValueChanged += MoveGeneratorParameter_ValueChanged;
+            MoveEvaluatorParameter.ValueChanged += MoveEvaluatorParameter_ValueChanged;
+        }
+
+        public override void Prepare()
+        {
+            if (Problem != null && MoveGenerator != null && MoveMaker != null && MoveEvaluator != null)
+                base.Prepare();
+        }
+
+        #region Events
+        protected override void OnProblemChanged()
+        {
+            foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>())
+            {
+                op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
+            }
+            UpdateMoveGenerator();
+            UpdateMoveOperators();
+            UpdateAnalyzers();
+            Parameterize();
+            Problem.Evaluator.QualityParameter.ActualNameChanged += Evaluator_QualityParameter_ActualNameChanged;
+            base.OnProblemChanged();
+        }
+        protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e)
+        {
+            Parameterize();
+            base.Problem_SolutionCreatorChanged(sender, e);
+        }
+        protected override void Problem_EvaluatorChanged(object sender, EventArgs e)
+        {
+            Parameterize();
+            Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+            base.Problem_EvaluatorChanged(sender, e);
+        }
+        protected override void Problem_OperatorsChanged(object sender, EventArgs e)
+        {
+            foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>())
+            {
+                op.MoveQualityParameter.ActualNameChanged -= MoveEvaluator_MoveQualityParameter_ActualNameChanged;
+                op.MoveQualityParameter.ActualNameChanged += MoveEvaluator_MoveQualityParameter_ActualNameChanged;
+            }
+            UpdateMoveGenerator();
+            UpdateMoveOperators();
+            UpdateAnalyzers();
+            Parameterize();
+            base.Problem_OperatorsChanged(sender, e);
+        }
+        private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e)
+        {
+            Parameterize();
+        }
+        private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e)
+        {
+            UpdateMoveOperators();
+        }
+        private void MoveEvaluatorParameter_ValueChanged(object sender, EventArgs e)
+        {
+            Parameterize();
+        }
+        private void MoveEvaluator_MoveQualityParameter_ActualNameChanged(object sender, EventArgs e)
+        {
+            if (sender == MoveEvaluator) Parameterize();
+        }
+        #endregion
+
+        #region Helpers
+
+        private void UpdateMoveGenerator()
+        {
+            var oldMoveGenerator = MoveGenerator;
+            var defaultMoveGenerator = Problem.Operators.OfType<IMultiMoveGenerator>().FirstOrDefault();
+
+            MoveGeneratorParameter.ValidValues.Clear();
+
+            if (Problem != null)
+            {
+                foreach (var generator in Problem.Operators.OfType<IMultiMoveGenerator>().OrderBy(x => x.Name))
+                    MoveGeneratorParameter.ValidValues.Add(generator);
+            }
+
+            if (oldMoveGenerator != null)
+            {
+                var newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+                if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+                else oldMoveGenerator = null;
+            }
+            if (oldMoveGenerator == null && defaultMoveGenerator != null)
+                MoveGenerator = defaultMoveGenerator;
+
+            UpdateMoveOperators();
+        }
+
+        private void UpdateMoveOperators()
+        {
+            var oldMoveMaker = MoveMaker;
+            var oldMoveEvaluator = MoveEvaluator;
+
+            MoveMakerParameter.ValidValues.Clear();
+            MoveEvaluatorParameter.ValidValues.Clear();
+
+            if (MoveGenerator != null)
+            {
+                var moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+                foreach (var type in moveTypes.ToList())
+                {
+                    if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+                        moveTypes.Remove(type);
+                }
+                var operators = Problem.Operators.Where(op => moveTypes.Any(m => m.IsInstanceOfType(op))).ToList();
+                var defaultMoveMaker = operators.OfType<IMoveMaker>().FirstOrDefault();
+                var defaultMoveEvaluator = operators.OfType<ISingleObjectiveMoveEvaluator>().FirstOrDefault();
+
+                foreach (var moveMaker in operators.OfType<IMoveMaker>().OrderBy(op => op.Name))
+                    MoveMakerParameter.ValidValues.Add(moveMaker);
+
+                foreach (var moveEvaluator in operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(op => op.Name))
+                    MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
+
+                if (oldMoveMaker != null)
+                {
+                    var mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+                    if (mm != null) MoveMaker = mm;
+                    else oldMoveMaker = null;
+                }
+                if (oldMoveMaker == null && defaultMoveMaker != null)
+                    MoveMaker = defaultMoveMaker;
+
+                if (oldMoveEvaluator != null)
+                {
+                    var me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+                    if (me != null) MoveEvaluator = me;
+                    else oldMoveEvaluator = null;
+                }
+                if (oldMoveEvaluator == null & defaultMoveEvaluator != null)
+                    MoveEvaluator = defaultMoveEvaluator;
+            }
+        }
+
+        private void UpdateAnalyzers()
+        {
+            Analyzer.Operators.Clear();
+            if (Problem != null)
+            {
+                foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>())
+                {
+                    foreach (var param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+                        param.Depth = 0;
+                    Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
+                }
+            }
+            var qualityAnalyzer = new QualityAnalyzer();
+            var temperatureAnalyzer = new SingleValueAnalyzer { Name = TemperatureAnalyzerName };
+            Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
+            Analyzer.Operators.Add(temperatureAnalyzer, temperatureAnalyzer.EnabledByDefault);
+        }
+
+        private void Parameterize()
+        {
+
+            #region IStochasticOperator
+            if (Problem != null)
+            {
+                foreach (var op in Problem.Operators.OfType<IStochasticOperator>())
+                {
+                    op.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+                    op.RandomParameter.Hidden = true;
+                }
+            }
+            #endregion
+
+            #region IIterationBasedOperator
+            if (Problem != null)
+            {
+                foreach (var op in Problem.Operators.OfType<IIterationBasedOperator>())
+                {
+                    op.IterationsParameter.ActualName = IterationsName;
+                    op.IterationsParameter.Hidden = true;
+                    op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+                    op.MaximumIterationsParameter.Hidden = true;
+                }
+            }
+            #endregion
+
+            #region Analyzers
+
+            foreach (var qualityAnalyzer in Analyzer.Operators.OfType<QualityAnalyzer>())
+            {
+                qualityAnalyzer.ResultsParameter.ActualName = ResultsName;
+                if (Problem != null)
+                {
+                    qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+                    qualityAnalyzer.MaximizationParameter.Hidden = true;
+                    qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+                    qualityAnalyzer.QualityParameter.Depth = 0;
+                    qualityAnalyzer.QualityParameter.Hidden = true;
+                    qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
+                    qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
+                }
+                else
+                {
+                    qualityAnalyzer.MaximizationParameter.Hidden = false;
+                    qualityAnalyzer.QualityParameter.Hidden = false;
+                    qualityAnalyzer.BestKnownQualityParameter.Hidden = false;
+                }
+            }
+
+            var temperatureAnalyzer = Analyzer.Operators.OfType<SingleValueAnalyzer>().FirstOrDefault(x => x.Name == TemperatureAnalyzerName);
+            if (temperatureAnalyzer != null)
+            {
+                temperatureAnalyzer.ResultsParameter.ActualName = ResultsName;
+                temperatureAnalyzer.ResultsParameter.Hidden = true;
+                temperatureAnalyzer.ValueParameter.ActualName = TemperatureName;
+                temperatureAnalyzer.ValueParameter.Hidden = true;
+                temperatureAnalyzer.ValuesParameter.ActualName = TemperatureChartName;
+                temperatureAnalyzer.ValuesParameter.Hidden = true;
+            }
+
+            #endregion
+
+            #region SolutionCreator
+            if (Problem != null)
+            {
+                SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+                SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+            }
+            #endregion
+
+            #region Annealing/Reheating Operators
+            foreach (var op in AnnealingOperatorParameter.ValidValues)
+            {
+                op.IndexParameter.ActualName = IterationsName;
+                op.IndexParameter.Hidden = true;
+                op.StartIndexParameter.Value = null;
+                op.StartIndexParameter.ActualName = TemperatureStartIndexName;
+                op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
+                op.ValueParameter.ActualName = TemperatureName;
+                op.ValueParameter.Hidden = true;
+                op.StartValueParameter.ActualName = StartTemperatureName;
+                op.StartValueParameter.Hidden = true;
+                op.EndValueParameter.ActualName = LowerTemperatureParameter.Name;
+                op.EndValueParameter.Hidden = true;
+            }
+            
+            foreach(var op in HeatingStrategyOperatorParameter.ValidValues)
+            {
+                op.Parameterize();
+            }
+
+            #endregion
+
+            #region Move Operators
+            if (Problem != null)
+            {
+                foreach (var op in Problem.Operators.OfType<IMultiMoveGenerator>())
+                {
+                    op.SampleSizeParameter.Value = new IntValue(1);
+                    op.SampleSizeParameter.Hidden = true;
+                }
+                foreach (var op in Problem.Operators.OfType<IMoveMaker>())
+                {
+                    op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+                    op.QualityParameter.Hidden = true;
+                    if (MoveEvaluator != null)
+                    {
+                        op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+                        op.MoveQualityParameter.Hidden = true;
+                    }
+                    else
+                    {
+                        op.MoveQualityParameter.Hidden = false;
+                    }
+                }
+                foreach (var op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>())
+                {
+                    op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+                    op.QualityParameter.Hidden = true;
+                }
+            }
+            #endregion
+
+            #region MainLoop
+            if (Problem != null)
+            {
+                MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
+                MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+                MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+                if (MoveEvaluator != null)
+                    MainLoop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+            }
+            #endregion
+
+        }
+        #endregion
     }
-    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
-      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
-      set { base.Problem = value; }
-    }
-    #endregion
-
-    #region Parameter Properties
-    private ValueParameter<IntValue> SeedParameter {
-      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
-    }
-    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
-      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
-    }
-    public IConstrainedValueParameter<IMultiMoveGenerator> MoveGeneratorParameter {
-      get { return (IConstrainedValueParameter<IMultiMoveGenerator>)Parameters["MoveGenerator"]; }
-    }
-    public IConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
-      get { return (IConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
-    }
-    public IConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
-      get { return (IConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
-    }
-    public IConstrainedValueParameter<IDiscreteDoubleValueModifier> AnnealingOperatorParameter {
-      get { return (IConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["AnnealingOperator"]; }
-    }
-    private ValueParameter<IntValue> MaximumIterationsParameter {
-      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-    private ValueParameter<IntValue> InnerIterationsParameter {
-      get { return (ValueParameter<IntValue>)Parameters["InnerIterations"]; }
-    }
-    private ValueParameter<DoubleValue> StartTemperatureParameter {
-      get { return (ValueParameter<DoubleValue>)Parameters["StartTemperature"]; }
-    }
-    private ValueParameter<DoubleValue> EndTemperatureParameter {
-      get { return (ValueParameter<DoubleValue>)Parameters["EndTemperature"]; }
-    }
-    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
-      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
-    }
-    #endregion
-
-    #region Properties
-    public IntValue Seed {
-      get { return SeedParameter.Value; }
-      set { SeedParameter.Value = value; }
-    }
-    public BoolValue SetSeedRandomly {
-      get { return SetSeedRandomlyParameter.Value; }
-      set { SetSeedRandomlyParameter.Value = value; }
-    }
-    public IMultiMoveGenerator MoveGenerator {
-      get { return MoveGeneratorParameter.Value; }
-      set { MoveGeneratorParameter.Value = value; }
-    }
-    public IMoveMaker MoveMaker {
-      get { return MoveMakerParameter.Value; }
-      set { MoveMakerParameter.Value = value; }
-    }
-    public ISingleObjectiveMoveEvaluator MoveEvaluator {
-      get { return MoveEvaluatorParameter.Value; }
-      set { MoveEvaluatorParameter.Value = value; }
-    }
-    public IDiscreteDoubleValueModifier AnnealingOperator {
-      get { return AnnealingOperatorParameter.Value; }
-      set { AnnealingOperatorParameter.Value = value; }
-    }
-    public IntValue MaximumIterations {
-      get { return MaximumIterationsParameter.Value; }
-      set { MaximumIterationsParameter.Value = value; }
-    }
-    public IntValue InnerIterations {
-      get { return InnerIterationsParameter.Value; }
-      set { InnerIterationsParameter.Value = value; }
-    }
-    public DoubleValue StartTemperature {
-      get { return StartTemperatureParameter.Value; }
-      set { StartTemperatureParameter.Value = value; }
-    }
-    public DoubleValue EndTemperature {
-      get { return EndTemperatureParameter.Value; }
-      set { EndTemperatureParameter.Value = value; }
-    }
-    public MultiAnalyzer Analyzer {
-      get { return AnalyzerParameter.Value; }
-      set { AnalyzerParameter.Value = value; }
-    }
-    private RandomCreator RandomCreator {
-      get { return (RandomCreator)OperatorGraph.InitialOperator; }
-    }
-    private SolutionsCreator SolutionsCreator {
-      get { return (SolutionsCreator)RandomCreator.Successor; }
-    }
-    private SimulatedAnnealingMainLoop MainLoop {
-      get { return FindMainLoop(SolutionsCreator.Successor); }
-    }
-    [Storable]
-    private QualityAnalyzer qualityAnalyzer;
-    [Storable]
-    private SingleValueAnalyzer temperatureAnalyzer;
-    #endregion
-
-    [StorableConstructor]
-    private SimulatedAnnealing(bool deserializing) : base(deserializing) { }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (temperatureAnalyzer == null) {
-        temperatureAnalyzer = new SingleValueAnalyzer();
-        temperatureAnalyzer.Name = "TemperatureAnalyzer";
-        temperatureAnalyzer.ResultsParameter.ActualName = "Results";
-        temperatureAnalyzer.ValueParameter.ActualName = "Temperature";
-        temperatureAnalyzer.ValuesParameter.ActualName = "Temperature Chart";
-        Analyzer.Operators.Add(temperatureAnalyzer);
-      }
-      Initialize();
-    }
-    private SimulatedAnnealing(SimulatedAnnealing original, Cloner cloner)
-      : base(original, cloner) {
-      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
-      temperatureAnalyzer = cloner.Clone(original.temperatureAnalyzer);
-      Initialize();
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SimulatedAnnealing(this, cloner);
-    }
-    public SimulatedAnnealing()
-      : base() {
-      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
-      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
-      Parameters.Add(new ConstrainedValueParameter<IMultiMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
-      Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
-      Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
-      Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>("AnnealingOperator", "The operator used to modify the temperature."));
-      Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(100)));
-      Parameters.Add(new ValueParameter<IntValue>("InnerIterations", "The amount of inner iterations (number of moves before temperature is adjusted again).", new IntValue(10)));
-      Parameters.Add(new ValueParameter<DoubleValue>("StartTemperature", "The initial temperature.", new DoubleValue(100)));
-      Parameters.Add(new ValueParameter<DoubleValue>("EndTemperature", "The final temperature which should be reached when iterations reaches maximum iterations.", new DoubleValue(1e-6)));
-      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze each generation.", new MultiAnalyzer()));
-
-      RandomCreator randomCreator = new RandomCreator();
-      SolutionsCreator solutionsCreator = new SolutionsCreator();
-      VariableCreator variableCreator = new VariableCreator();
-      ResultsCollector resultsCollector = new ResultsCollector();
-      SimulatedAnnealingMainLoop mainLoop = new SimulatedAnnealingMainLoop();
-      OperatorGraph.InitialOperator = randomCreator;
-
-      randomCreator.RandomParameter.ActualName = "Random";
-      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
-      randomCreator.SeedParameter.Value = null;
-      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
-      randomCreator.SetSeedRandomlyParameter.Value = null;
-      randomCreator.Successor = solutionsCreator;
-
-      solutionsCreator.NumberOfSolutions = new IntValue(1);
-      solutionsCreator.Successor = variableCreator;
-
-      variableCreator.Name = "Initialize EvaluatedMoves";
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedMoves", new IntValue()));
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
-      variableCreator.Successor = resultsCollector;
-
-      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Moves", null, "EvaluatedMoves"));
-      resultsCollector.ResultsParameter.ActualName = "Results";
-      resultsCollector.Successor = mainLoop;
-
-      mainLoop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
-      mainLoop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
-      mainLoop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
-      mainLoop.AnnealingOperatorParameter.ActualName = AnnealingOperatorParameter.Name;
-      mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
-      mainLoop.TemperatureParameter.ActualName = "Temperature";
-      mainLoop.StartTemperatureParameter.ActualName = StartTemperatureParameter.Name;
-      mainLoop.EndTemperatureParameter.ActualName = EndTemperatureParameter.Name;
-      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
-      mainLoop.ResultsParameter.ActualName = "Results";
-      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
-      mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
-      mainLoop.IterationsParameter.ActualName = "Iterations";
-
-      foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
-        AnnealingOperatorParameter.ValidValues.Add(op);
-      ParameterizeAnnealingOperators();
-
-      qualityAnalyzer = new QualityAnalyzer();
-      temperatureAnalyzer = new SingleValueAnalyzer();
-      temperatureAnalyzer.Name = "TemperatureAnalyzer";
-      ParameterizeAnalyzers();
-      UpdateAnalyzers();
-
-      Initialize();
-    }
-
-    public override void Prepare() {
-      if (Problem != null && MoveGenerator != null && MoveMaker != null && MoveEvaluator != null)
-        base.Prepare();
-    }
-
-    #region Events
-    protected override void OnProblemChanged() {
-      ParameterizeStochasticOperator(Problem.SolutionCreator);
-      ParameterizeStochasticOperator(Problem.Evaluator);
-      foreach (IOperator op in Problem.Operators.OfType<IOperator>()) ParameterizeStochasticOperator(op);
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-      }
-      ParameterizeSolutionsCreator();
-      ParameterizeMainLoop();
-      UpdateMoveGenerator();
-      UpdateMoveParameters();
-      UpdateAnalyzers();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeMoveGenerators();
-      ParameterizeAnalyzers();
-      ParameterizeIterationBasedOperators();
-      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-      base.OnProblemChanged();
-    }
-    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
-      ParameterizeStochasticOperator(Problem.SolutionCreator);
-      ParameterizeSolutionsCreator();
-      base.Problem_SolutionCreatorChanged(sender, e);
-    }
-    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
-      ParameterizeStochasticOperator(Problem.Evaluator);
-      ParameterizeSolutionsCreator();
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeAnalyzers();
-      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-      base.Problem_EvaluatorChanged(sender, e);
-    }
-    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
-      foreach (IOperator op in Problem.Operators.OfType<IOperator>()) ParameterizeStochasticOperator(op);
-      // This may seem pointless, but some operators already have the eventhandler registered, others don't
-      // FIXME: Is there another way to solve this problem?
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.MoveQualityParameter.ActualNameChanged -= new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-        op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-      }
-      UpdateMoveGenerator();
-      UpdateMoveParameters();
-      UpdateAnalyzers();
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeMoveGenerators();
-      ParameterizeIterationBasedOperators();
-      base.Problem_OperatorsChanged(sender, e);
-    }
-    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-      ParameterizeAnalyzers();
-    }
-    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
-      UpdateMoveParameters();
-    }
-    private void MoveEvaluatorParameter_ValueChanged(object sender, EventArgs e) {
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-    }
-    private void MoveEvaluator_MoveQualityParameter_ActualNameChanged(object sender, EventArgs e) {
-      ParameterizeMainLoop();
-      ParameterizeMoveEvaluators();
-      ParameterizeMoveMakers();
-    }
-    #endregion
-
-    #region Helpers
-    private void Initialize() {
-      if (Problem != null) {
-        Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
-        foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-          op.MoveQualityParameter.ActualNameChanged += new EventHandler(MoveEvaluator_MoveQualityParameter_ActualNameChanged);
-        }
-      }
-      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
-      MoveEvaluatorParameter.ValueChanged += new EventHandler(MoveEvaluatorParameter_ValueChanged);
-    }
-    private void UpdateMoveGenerator() {
-      IMultiMoveGenerator oldMoveGenerator = MoveGenerator;
-      IMultiMoveGenerator defaultMoveGenerator = Problem.Operators.OfType<IMultiMoveGenerator>().FirstOrDefault();
-      MoveGeneratorParameter.ValidValues.Clear();
-      if (Problem != null) {
-        foreach (IMultiMoveGenerator generator in Problem.Operators.OfType<IMultiMoveGenerator>().OrderBy(x => x.Name))
-          MoveGeneratorParameter.ValidValues.Add(generator);
-      }
-      if (oldMoveGenerator != null) {
-        IMultiMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
-        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
-        else oldMoveGenerator = null;
-      }
-      if (oldMoveGenerator == null && defaultMoveGenerator != null)
-        MoveGenerator = defaultMoveGenerator;
-      if (MoveGenerator == null) {
-        ClearMoveParameters();
-      }
-    }
-    private void ParameterizeAnalyzers() {
-      qualityAnalyzer.ResultsParameter.ActualName = "Results";
-      if (Problem != null) {
-        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
-        qualityAnalyzer.MaximizationParameter.Hidden = true;
-        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        qualityAnalyzer.QualityParameter.Depth = 0;
-        qualityAnalyzer.QualityParameter.Hidden = true;
-        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
-        qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
-      } else {
-        qualityAnalyzer.MaximizationParameter.Hidden = false;
-        qualityAnalyzer.QualityParameter.Hidden = false;
-        qualityAnalyzer.BestKnownQualityParameter.Hidden = false;
-        temperatureAnalyzer.ResultsParameter.ActualName = "Results";
-        temperatureAnalyzer.ValueParameter.ActualName = "Temperature";
-        temperatureAnalyzer.ValuesParameter.ActualName = "Temperature Chart";
-      }
-    }
-    private void UpdateMoveParameters() {
-      IMoveMaker oldMoveMaker = MoveMaker;
-      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
-      ClearMoveParameters();
-
-      if (MoveGenerator != null) {
-        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
-        foreach (Type type in moveTypes.ToList()) {
-          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
-            moveTypes.Remove(type);
-        }
-        var operators = Problem.Operators.Where(op => moveTypes.Any(m => m.IsInstanceOfType(op))).ToList();
-        IMoveMaker defaultMoveMaker = operators.OfType<IMoveMaker>().FirstOrDefault();
-        ISingleObjectiveMoveEvaluator defaultMoveEvaluator = operators.OfType<ISingleObjectiveMoveEvaluator>().FirstOrDefault();
-
-        foreach (IMoveMaker moveMaker in operators.OfType<IMoveMaker>().OrderBy(op => op.Name))
-          MoveMakerParameter.ValidValues.Add(moveMaker);
-        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(op => op.Name))
-          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
-
-        if (oldMoveMaker != null) {
-          IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
-          if (mm != null) MoveMaker = mm;
-          else oldMoveMaker = null;
-        }
-        if (oldMoveMaker == null && defaultMoveMaker != null)
-          MoveMaker = defaultMoveMaker;
-
-        if (oldMoveEvaluator != null) {
-          ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
-          if (me != null) MoveEvaluator = me;
-          else oldMoveEvaluator = null;
-        }
-        if (oldMoveEvaluator == null & defaultMoveEvaluator != null)
-          MoveEvaluator = defaultMoveEvaluator;
-      }
-    }
-    private void ClearMoveParameters() {
-      MoveMakerParameter.ValidValues.Clear();
-      MoveEvaluatorParameter.ValidValues.Clear();
-    }
-    private void ParameterizeSolutionsCreator() {
-      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
-      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
-    }
-    private void ParameterizeMainLoop() {
-      if (Problem != null) {
-        MainLoop.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
-        MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
-        MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-      }
-      if (MoveEvaluator != null)
-        MainLoop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
-    }
-    private void ParameterizeStochasticOperator(IOperator op) {
-      if (op is IStochasticOperator) {
-        IStochasticOperator stOp = (IStochasticOperator)op;
-        stOp.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
-        stOp.RandomParameter.Hidden = true;
-      }
-    }
-    private void ParameterizeMoveEvaluators() {
-      foreach (ISingleObjectiveMoveEvaluator op in Problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        op.QualityParameter.Hidden = true;
-      }
-    }
-    private void ParameterizeMoveMakers() {
-      foreach (IMoveMaker op in Problem.Operators.OfType<IMoveMaker>()) {
-        op.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
-        op.QualityParameter.Hidden = true;
-        if (MoveEvaluator != null) {
-          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
-          op.MoveQualityParameter.Hidden = true;
-        } else {
-          op.MoveQualityParameter.Hidden = false;
-        }
-      }
-    }
-    private void ParameterizeAnnealingOperators() {
-      foreach (IDiscreteDoubleValueModifier op in AnnealingOperatorParameter.ValidValues) {
-        op.IndexParameter.ActualName = "Iterations";
-        op.IndexParameter.Hidden = true;
-        op.StartIndexParameter.Value = new IntValue(0);
-        op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
-        op.ValueParameter.ActualName = "Temperature";
-        op.ValueParameter.Hidden = true;
-        op.StartValueParameter.ActualName = StartTemperatureParameter.Name;
-        op.StartValueParameter.Hidden = true;
-        op.EndValueParameter.ActualName = EndTemperatureParameter.Name;
-        op.EndValueParameter.Hidden = true;
-        ParameterizeStochasticOperator(op);
-      }
-    }
-    private void ParameterizeMoveGenerators() {
-      foreach (IMultiMoveGenerator op in Problem.Operators.OfType<IMultiMoveGenerator>()) {
-        op.SampleSizeParameter.ActualName = InnerIterationsParameter.Name;
-        op.SampleSizeParameter.Hidden = true;
-      }
-    }
-    private void ParameterizeIterationBasedOperators() {
-      if (Problem != null) {
-        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
-          op.IterationsParameter.ActualName = "Iterations";
-          op.IterationsParameter.Hidden = true;
-          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
-          op.MaximumIterationsParameter.Hidden = true;
-        }
-      }
-    }
-    private void UpdateAnalyzers() {
-      Analyzer.Operators.Clear();
-      if (Problem != null) {
-        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
-          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
-            param.Depth = 0;
-          Analyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
-        }
-      }
-      Analyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
-      Analyzer.Operators.Add(temperatureAnalyzer, temperatureAnalyzer.EnabledByDefault);
-    }
-    private SimulatedAnnealingMainLoop FindMainLoop(IOperator start) {
-      IOperator mainLoop = start;
-      while (mainLoop != null && !(mainLoop is SimulatedAnnealingMainLoop))
-        mainLoop = ((SingleSuccessorOperator)mainLoop).Successor;
-      if (mainLoop == null) return null;
-      else return (SimulatedAnnealingMainLoop)mainLoop;
-    }
-    #endregion
-  }
 }
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 14406)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 14452)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -28,227 +28,287 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
-namespace HeuristicLab.Algorithms.SimulatedAnnealing {
-  /// <summary>
-  /// An operator which represents a simulated annealing.
-  /// </summary>
-  [Item("SimulatedAnnealingMainLoop", "An operator which represents the main loop of a simulated annealing algorithm.")]
-  [StorableClass]
-  public sealed class SimulatedAnnealingMainLoop : AlgorithmOperator {
-    #region Parameter properties
-    public ValueLookupParameter<IRandom> RandomParameter {
-      get { return (ValueLookupParameter<IRandom>)Parameters["Random"]; }
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    [Item("SimulatedAnnealingMainLoop", "An operator which represents the main loop of a simulated annealing algorithm.")]
+    [StorableClass]
+    public sealed class SimulatedAnnealingMainLoop : AlgorithmOperator
+    {
+        #region Strings
+        private const string MoveGeneratorName = "MoveGenerator";
+        private const string MoveEvaluatorName = "MoveEvaluator";
+        private const string MoveMakerName = "MoveMaker";
+        private const string AnnealingOperatorName = "AnnealingOperator";
+        private const string HeatingStrategyOperatorName = "HeatingStrategyOperator";
+        private const string MaximumIterationsName = "MaximumIterations";
+        private const string LowerTemperatureName = "LowerTemperature";
+        private const string AnalyzerName = "Analyzer";
+        private const string RandomName = "Random";
+        private const string EvaluatedMovesName = "EvaluatedMoves";
+        private const string IterationsName = "Iterations";
+        private const string TemperatureStartIndexName = "TemperatureStartIndex";
+        private const string CoolingName = "Cooling";
+        private const string StartTemperatureName = "StartTemperature";
+        private const string EndTemperatureName = "EndTemperature";
+        private const string TemperatureName = "Temperature";
+        private const string ResultsName = "Results";
+        private const string MaximizationName = "Maximization";
+        private const string QualityName = "Quality";
+        private const string BestKnownQualityName = "BestKnownQuality";
+        private const string MoveQualityName = "MoveQuality";
+        private const string IsAcceptedName = "IsAccepted";
+        private const string TerminateName = "Terminate";
+        private const string AcceptanceMemoryName = "AcceptanceMemory";
+        #endregion
+
+        #region Parameter properties
+        public IValueLookupParameter<IRandom> RandomParameter
+        {
+            get { return (IValueLookupParameter<IRandom>)Parameters[RandomName]; }
+        }
+        public IValueLookupParameter<BoolValue> MaximizationParameter
+        {
+            get { return (IValueLookupParameter<BoolValue>)Parameters[MaximizationName]; }
+        }
+        public ILookupParameter<DoubleValue> QualityParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[QualityName]; }
+        }
+        public IValueLookupParameter<DoubleValue> BestKnownQualityParameter
+        {
+            get { return (IValueLookupParameter<DoubleValue>)Parameters[BestKnownQualityName]; }
+        }
+        public ILookupParameter<DoubleValue> MoveQualityParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[MoveQualityName]; }
+        }
+        public ILookupParameter<DoubleValue> TemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
+        }
+        public IValueLookupParameter<DoubleValue> LowerTemperatureParameter
+        {
+            get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
+        }
+        public ILookupParameter<IntValue> IterationsParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
+        }
+        public IValueLookupParameter<IntValue> MaximumIterationsParameter
+        {
+            get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
+        }
+        public IValueLookupParameter<IOperator> MoveGeneratorParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[MoveGeneratorName]; }
+        }
+        public IValueLookupParameter<IOperator> MoveEvaluatorParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[MoveEvaluatorName]; }
+        }
+        public IValueLookupParameter<IOperator> MoveMakerParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[MoveMakerName]; }
+        }
+        public IValueLookupParameter<IOperator> AnnealingOperatorParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[AnnealingOperatorName]; }
+        }
+        public IValueLookupParameter<IOperator> HeatingStrategyOperatorParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[HeatingStrategyOperatorName]; }
+        }
+        public IValueLookupParameter<IOperator> AnalyzerParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[AnalyzerName]; }
+        }
+        public IValueLookupParameter<VariableCollection> ResultsParameter
+        {
+            get { return (IValueLookupParameter<VariableCollection>)Parameters[ResultsName]; }
+        }
+        public ILookupParameter<IntValue> EvaluatedMovesParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[EvaluatedMovesName]; }
+        }
+        public ILookupParameter<DoubleValue> StartTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
+        }
+        public ILookupParameter<DoubleValue> EndTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
+        }
+        public ILookupParameter<IntValue> TemperatureStartIndexParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
+        }
+        public ILookupParameter<BoolValue> CoolingParameter
+        {
+            get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
+        }
+        #endregion
+
+        [StorableConstructor]
+        private SimulatedAnnealingMainLoop(bool deserializing) : base(deserializing) { }
+        private SimulatedAnnealingMainLoop(SimulatedAnnealingMainLoop original, Cloner cloner)
+          : base(original, cloner)
+        {
+        }
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new SimulatedAnnealingMainLoop(this, cloner);
+        }
+        public SimulatedAnnealingMainLoop()
+          : base()
+        {
+            Initialize();
+        }
+
+        private void Initialize()
+        {
+            #region Create parameters
+            Parameters.Add(new ValueLookupParameter<IRandom>(RandomName, "A pseudo random number generator."));
+            Parameters.Add(new ValueLookupParameter<BoolValue>(MaximizationName, "True if the problem is a maximization problem, otherwise false."));
+            Parameters.Add(new LookupParameter<DoubleValue>(QualityName, "The value which represents the quality of a solution."));
+            Parameters.Add(new ValueLookupParameter<DoubleValue>(BestKnownQualityName, "The best known quality value found so far."));
+            Parameters.Add(new LookupParameter<DoubleValue>(MoveQualityName, "The value which represents the quality of a move."));
+            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
+            Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerTemperatureName, "The lower bound of the temperature."));
+            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
+            Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
+
+            Parameters.Add(new ValueLookupParameter<IOperator>(MoveGeneratorName, "The operator that generates the moves."));
+            Parameters.Add(new ValueLookupParameter<IOperator>(MoveEvaluatorName, "The operator that evaluates a move."));
+            Parameters.Add(new ValueLookupParameter<IOperator>(MoveMakerName, "The operator that performs a move and updates the quality."));
+            Parameters.Add(new ValueLookupParameter<IOperator>(AnnealingOperatorName, "The operator that cools the temperature."));
+            Parameters.Add(new ValueLookupParameter<IOperator>(HeatingStrategyOperatorName, "The operator that heats the temperature."));
+
+            Parameters.Add(new ValueLookupParameter<IOperator>(AnalyzerName, "The operator used to analyze each generation."));
+            Parameters.Add(new ValueLookupParameter<VariableCollection>(ResultsName, "The variable collection where results should be stored."));
+            Parameters.Add(new LookupParameter<IntValue>(EvaluatedMovesName, "The number of evaluated moves."));
+
+            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
+            Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
+            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
+            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
+            #endregion
+
+            #region Create operators
+            var variableCreator = new VariableCreator();
+            var ssp1 = new SubScopesProcessor();
+            var analyzer1 = new Placeholder();
+            var ssp2 = new SubScopesProcessor();
+            var resultsCollector = new ResultsCollector();
+            var mainProcessor = new SubScopesProcessor();
+            var moveGenerator = new Placeholder();
+            var moveEvaluationProcessor = new SubScopesProcessor();
+            var moveEvaluator = new Placeholder();
+            var evaluatedMovesCounter = new IntCounter();
+            var qualityComparator = new ProbabilisticQualityComparator();
+            var acceptsQualityBranch = new ConditionalBranch();
+            var moveMaker = new Placeholder();
+            var temperatureController = new TemperatureController();
+            var subScopesRemover = new SubScopesRemover();
+            var iterationsCounter = new IntCounter();
+            var iterationsComparator = new Comparator();
+            var ssp3 = new SubScopesProcessor();
+            var analyzer2 = new Placeholder();
+            var iterationsTermination = new ConditionalBranch();
+
+            variableCreator.Name = "Initialize Memory";
+            variableCreator.CollectedValues.Add(new ValueParameter<ItemList<BoolValue>>(AcceptanceMemoryName, new ItemList<BoolValue>()));
+
+            analyzer1.Name = "Analyzer";
+            analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+            moveGenerator.Name = "Move generator";
+            moveGenerator.OperatorParameter.ActualName = MoveGeneratorParameter.Name;
+
+            moveEvaluator.Name = "Move evaluator";
+            moveEvaluator.OperatorParameter.ActualName = MoveEvaluatorParameter.Name;
+
+            evaluatedMovesCounter.Name = "EvaluatedMoves++";
+            evaluatedMovesCounter.ValueParameter.ActualName = EvaluatedMovesParameter.Name;
+            evaluatedMovesCounter.Increment = new IntValue(1);
+
+            qualityComparator.LeftSideParameter.ActualName = MoveQualityParameter.Name;
+            qualityComparator.RightSideParameter.ActualName = QualityParameter.Name;
+            qualityComparator.ResultParameter.ActualName = IsAcceptedName;
+            qualityComparator.DampeningParameter.ActualName = TemperatureParameter.Name;
+
+            acceptsQualityBranch.ConditionParameter.ActualName = IsAcceptedName;
+
+            moveMaker.Name = "Move maker";
+            moveMaker.OperatorParameter.ActualName = MoveMakerParameter.Name;
+
+            temperatureController.AnnealingOperatorParameter.ActualName = AnnealingOperatorParameter.Name;
+            temperatureController.AcceptanceMemoryParameter.ActualName = AcceptanceMemoryName;
+            temperatureController.CoolingParameter.ActualName = CoolingParameter.Name;
+            temperatureController.EndTemperatureParameter.ActualName = EndTemperatureParameter.Name;
+            temperatureController.HeatingStrategyOperatorParameter.ActualName = HeatingStrategyOperatorParameter.Name;
+            temperatureController.IsAcceptedParameter.ActualName = IsAcceptedName;
+            temperatureController.IterationsParameter.ActualName = IterationsParameter.Name;
+            temperatureController.LowerTemperatureParameter.ActualName = LowerTemperatureParameter.Name;
+            temperatureController.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+            temperatureController.StartTemperatureParameter.ActualName = StartTemperatureParameter.Name;
+            temperatureController.TemperatureParameter.ActualName = TemperatureParameter.Name;
+            temperatureController.TemperatureStartIndexParameter.ActualName = TemperatureStartIndexParameter.Name;
+
+            subScopesRemover.RemoveAllSubScopes = true;
+
+            iterationsCounter.Name = "Iterations++";
+            iterationsCounter.Increment = new IntValue(1);
+            iterationsCounter.ValueParameter.ActualName = IterationsParameter.Name;
+
+            iterationsComparator.Name = "Iterations >= MaximumIterations";
+            iterationsComparator.LeftSideParameter.ActualName = IterationsParameter.Name;
+            iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
+            iterationsComparator.ResultParameter.ActualName = TerminateName;
+            iterationsComparator.Comparison.Value = ComparisonType.GreaterOrEqual;
+
+            analyzer2.Name = "Analyzer (placeholder)";
+            analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+            iterationsTermination.Name = "Iterations termination condition";
+            iterationsTermination.ConditionParameter.ActualName = TerminateName;
+            #endregion
+
+            #region Create operator graph
+            OperatorGraph.InitialOperator = variableCreator;
+            variableCreator.Successor = ssp1;
+            ssp1.Operators.Add(analyzer1);
+            ssp1.Successor = ssp2;
+            analyzer1.Successor = null;
+            ssp2.Operators.Add(resultsCollector);
+            ssp2.Successor = mainProcessor;
+            resultsCollector.Successor = null;
+            mainProcessor.Operators.Add(moveGenerator);
+            mainProcessor.Successor = iterationsCounter;
+            moveGenerator.Successor = moveEvaluationProcessor;
+            moveEvaluationProcessor.Operators.Add(moveEvaluator);
+            moveEvaluationProcessor.Successor = evaluatedMovesCounter;
+            moveEvaluator.Successor = qualityComparator;
+            qualityComparator.Successor = acceptsQualityBranch;
+            acceptsQualityBranch.TrueBranch = moveMaker;
+            acceptsQualityBranch.FalseBranch = null;
+            acceptsQualityBranch.Successor = temperatureController;
+            moveMaker.Successor = null;
+            temperatureController.Successor = null;
+            evaluatedMovesCounter.Successor = subScopesRemover;
+            subScopesRemover.Successor = null;
+            iterationsCounter.Successor = iterationsComparator;
+            iterationsComparator.Successor = ssp3;
+            ssp3.Operators.Add(analyzer2);
+            ssp3.Successor = iterationsTermination;
+            iterationsTermination.TrueBranch = null;
+            iterationsTermination.FalseBranch = mainProcessor;
+            #endregion
+        }
+
+        public override IOperation Apply()
+        {
+            if (MoveGeneratorParameter.ActualValue == null || MoveEvaluatorParameter.ActualValue == null || MoveMakerParameter.ActualValue == null)
+                return null;
+            return base.Apply();
+        }
     }
-    public ValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public LookupParameter<DoubleValue> QualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
-    }
-    public LookupParameter<DoubleValue> MoveQualityParameter {
-      get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
-    }
-    public ILookupParameter<DoubleValue> TemperatureParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Temperature"]; }
-    }
-    public ValueLookupParameter<DoubleValue> StartTemperatureParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["StartTemperature"]; }
-    }
-    public ValueLookupParameter<DoubleValue> EndTemperatureParameter {
-      get { return (ValueLookupParameter<DoubleValue>)Parameters["EndTemperature"]; }
-    }
-    public ValueLookupParameter<IntValue> InnerIterationsParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["InnerIterations"]; }
-    }
-    public LookupParameter<IntValue> IterationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["Iterations"]; }
-    }
-    public ValueLookupParameter<IntValue> MaximumIterationsParameter {
-      get { return (ValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
-    }
-    public ValueLookupParameter<IOperator> MoveGeneratorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveGenerator"]; }
-    }
-    public ValueLookupParameter<IOperator> MoveEvaluatorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveEvaluator"]; }
-    }
-    public ValueLookupParameter<IOperator> MoveMakerParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["MoveMaker"]; }
-    }
-    public ValueLookupParameter<IOperator> AnnealingOperatorParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["AnnealingOperator"]; }
-    }
-    public ValueLookupParameter<IOperator> AnalyzerParameter {
-      get { return (ValueLookupParameter<IOperator>)Parameters["Analyzer"]; }
-    }
-    public ValueLookupParameter<VariableCollection> ResultsParameter {
-      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
-    }
-    public LookupParameter<IntValue> EvaluatedMovesParameter {
-      get { return (LookupParameter<IntValue>)Parameters["EvaluatedMoves"]; }
-    }
-    #endregion
-
-    [StorableConstructor]
-    private SimulatedAnnealingMainLoop(bool deserializing) : base(deserializing) { }
-    private SimulatedAnnealingMainLoop(SimulatedAnnealingMainLoop original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new SimulatedAnnealingMainLoop(this, cloner);
-    }
-    public SimulatedAnnealingMainLoop()
-      : base() {
-      Initialize();
-    }
-
-    private void Initialize() {
-      #region Create parameters
-      Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
-      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The value which represents the quality of a move."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Temperature", "The current temperature."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("StartTemperature", "The initial temperature."));
-      Parameters.Add(new ValueLookupParameter<DoubleValue>("EndTemperature", "The end temperature."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("InnerIterations", "The amount of inner iterations (number of moves before temperature is adjusted again)."));
-      Parameters.Add(new LookupParameter<IntValue>("Iterations", "The number of iterations."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations which should be processed."));
-
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveGenerator", "The operator that generates the moves."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveEvaluator", "The operator that evaluates a move."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("MoveMaker", "The operator that performs a move and updates the quality."));
-      Parameters.Add(new ValueLookupParameter<IOperator>("AnnealingOperator", "The operator that modifies the temperature."));
-
-      Parameters.Add(new ValueLookupParameter<IOperator>("Analyzer", "The operator used to analyze each generation."));
-      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
-      Parameters.Add(new LookupParameter<IntValue>("EvaluatedMoves", "The number of evaluated moves."));
-      #endregion
-
-      #region Create operators
-      Assigner temperatureInitializer = new Assigner();
-      ResultsCollector resultsCollector1 = new ResultsCollector();
-      SubScopesProcessor subScopesProcessor0 = new SubScopesProcessor();
-      Placeholder analyzer1 = new Placeholder();
-      SubScopesProcessor sssp = new SubScopesProcessor();
-      ResultsCollector resultsCollector = new ResultsCollector();
-      Placeholder annealingOperator = new Placeholder();
-      UniformSubScopesProcessor mainProcessor = new UniformSubScopesProcessor();
-      Placeholder moveGenerator = new Placeholder();
-      UniformSubScopesProcessor moveEvaluationProcessor = new UniformSubScopesProcessor();
-      Placeholder moveEvaluator = new Placeholder();
-      SubScopesCounter subScopesCounter = new SubScopesCounter();
-      ProbabilisticQualityComparator qualityComparator = new ProbabilisticQualityComparator();
-      ConditionalBranch improvesQualityBranch = new ConditionalBranch();
-      Placeholder moveMaker = new Placeholder();
-      SubScopesRemover subScopesRemover = new SubScopesRemover();
-      IntCounter iterationsCounter = new IntCounter();
-      Comparator iterationsComparator = new Comparator();
-      SubScopesProcessor subScopesProcessor1 = new SubScopesProcessor();
-      Placeholder analyzer2 = new Placeholder();
-      ConditionalBranch iterationsTermination = new ConditionalBranch();
-
-      temperatureInitializer.LeftSideParameter.ActualName = TemperatureParameter.ActualName;
-      temperatureInitializer.RightSideParameter.ActualName = StartTemperatureParameter.Name;
-
-      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>(IterationsParameter.Name));
-      resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
-
-      analyzer1.Name = "Analyzer (placeholder)";
-      analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
-
-      annealingOperator.Name = "Annealing operator (placeholder)";
-      annealingOperator.OperatorParameter.ActualName = AnnealingOperatorParameter.Name;
-
-      moveGenerator.Name = "Move generator (placeholder)";
-      moveGenerator.OperatorParameter.ActualName = MoveGeneratorParameter.Name;
-
-      moveEvaluator.Name = "Move evaluator (placeholder)";
-      moveEvaluator.OperatorParameter.ActualName = MoveEvaluatorParameter.Name;
-
-      subScopesCounter.Name = "Increment EvaluatedMoves";
-      subScopesCounter.ValueParameter.ActualName = EvaluatedMovesParameter.Name;
-
-      qualityComparator.LeftSideParameter.ActualName = MoveQualityParameter.Name;
-      qualityComparator.RightSideParameter.ActualName = QualityParameter.Name;
-      qualityComparator.ResultParameter.ActualName = "IsBetter";
-      qualityComparator.DampeningParameter.ActualName = "Temperature";
-
-      improvesQualityBranch.ConditionParameter.ActualName = "IsBetter";
-
-      moveMaker.Name = "Move maker (placeholder)";
-      moveMaker.OperatorParameter.ActualName = MoveMakerParameter.Name;
-
-      subScopesRemover.RemoveAllSubScopes = true;
-
-      iterationsCounter.Name = "Increment Iterations";
-      iterationsCounter.Increment = new IntValue(1);
-      iterationsCounter.ValueParameter.ActualName = IterationsParameter.Name;
-
-      iterationsComparator.Name = "Iterations >= MaximumIterations";
-      iterationsComparator.LeftSideParameter.ActualName = IterationsParameter.Name;
-      iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
-      iterationsComparator.ResultParameter.ActualName = "Terminate";
-      iterationsComparator.Comparison.Value = ComparisonType.GreaterOrEqual;
-
-      analyzer2.Name = "Analyzer (placeholder)";
-      analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name;
-
-      iterationsTermination.Name = "Iterations termination condition";
-      iterationsTermination.ConditionParameter.ActualName = "Terminate";
-      #endregion
-
-      #region Create operator graph
-      OperatorGraph.InitialOperator = temperatureInitializer;
-      temperatureInitializer.Successor = resultsCollector1;
-      resultsCollector1.Successor = subScopesProcessor0;
-      subScopesProcessor0.Operators.Add(analyzer1);
-      subScopesProcessor0.Successor = sssp;
-      analyzer1.Successor = null;
-      sssp.Operators.Add(resultsCollector);
-      sssp.Successor = annealingOperator;
-      resultsCollector.Successor = null;
-      annealingOperator.Successor = mainProcessor;
-      mainProcessor.Operator = moveGenerator;
-      mainProcessor.Successor = iterationsCounter;
-      moveGenerator.Successor = moveEvaluationProcessor;
-      moveEvaluationProcessor.Operator = moveEvaluator;
-      moveEvaluationProcessor.Successor = subScopesCounter;
-      moveEvaluator.Successor = qualityComparator;
-      qualityComparator.Successor = improvesQualityBranch;
-      improvesQualityBranch.TrueBranch = moveMaker;
-      improvesQualityBranch.FalseBranch = null;
-      improvesQualityBranch.Successor = null;
-      moveMaker.Successor = null;
-      subScopesCounter.Successor = subScopesRemover;
-      subScopesRemover.Successor = null;
-      iterationsCounter.Successor = iterationsComparator;
-      iterationsComparator.Successor = subScopesProcessor1;
-      subScopesProcessor1.Operators.Add(analyzer2);
-      subScopesProcessor1.Successor = iterationsTermination;
-      iterationsTermination.TrueBranch = null;
-      iterationsTermination.FalseBranch = annealingOperator;
-      #endregion
-    }
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      // BackwardsCompatibility3.3
-      #region Backwards compatible code (remove with 3.4)
-      if (!Parameters.ContainsKey("Iterations"))
-        Parameters.Add(new LookupParameter<IntValue>("Iterations", "The number of iterations."));
-      if (!Parameters.ContainsKey("Temperature"))
-        Parameters.Add(new LookupParameter<DoubleValue>("Temperature", "The current temperature."));
-      #endregion
-    }
-
-    public override IOperation Apply() {
-      if (MoveGeneratorParameter.ActualValue == null || MoveEvaluatorParameter.ActualValue == null || MoveMakerParameter.ActualValue == null)
-        return null;
-      return base.Apply();
-    }
-  }
 }
Index: branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/TemperatureController.cs
===================================================================
--- branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/TemperatureController.cs	(revision 14452)
+++ branches/jschiess/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/TemperatureController.cs	(revision 14452)
@@ -0,0 +1,169 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing
+{
+    [Item("TemperatureController", "Decides based on information from the heatingoperator, whether to use cooling or heating and calls the appropriate operator.")]
+    [StorableClass]
+    public class TemperatureController : SingleSuccessorOperator
+    {
+        #region Strings
+        private const string AnnealingOperatorName = "AnnealingOperator";
+        private const string HeatingStrategyOperatorName = "HeatingStrategyOperator";
+        private const string MaximumIterationsName = "MaximumIterations";
+        private const string LowerTemperatureName = "LowerTemperature";
+        private const string IterationsName = "Iterations";
+        private const string TemperatureStartIndexName = "TemperatureStartIndex";
+        private const string CoolingName = "Cooling";
+        private const string StartTemperatureName = "StartTemperature";
+        private const string EndTemperatureName = "EndTemperature";
+        private const string TemperatureName = "Temperature";
+        private const string IsAcceptedName = "IsAccepted";
+        private const string AcceptanceMemoryName = "AcceptanceMemory";
+        #endregion
+
+        #region Parameter Properties
+        public ILookupParameter<DoubleValue> TemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
+        }
+        public IValueLookupParameter<DoubleValue> LowerTemperatureParameter
+        {
+            get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
+        }
+        public ILookupParameter<DoubleValue> StartTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[StartTemperatureName]; }
+        }
+        public ILookupParameter<DoubleValue> EndTemperatureParameter
+        {
+            get { return (ILookupParameter<DoubleValue>)Parameters[EndTemperatureName]; }
+        }
+        public ILookupParameter<IntValue> TemperatureStartIndexParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[TemperatureStartIndexName]; }
+        }
+        public ILookupParameter<BoolValue> CoolingParameter
+        {
+            get { return (ILookupParameter<BoolValue>)Parameters[CoolingName]; }
+        }
+        public ILookupParameter<IntValue> IterationsParameter
+        {
+            get { return (ILookupParameter<IntValue>)Parameters[IterationsName]; }
+        }
+        public IValueLookupParameter<IntValue> MaximumIterationsParameter
+        {
+            get { return (IValueLookupParameter<IntValue>)Parameters[MaximumIterationsName]; }
+        }
+        public IValueLookupParameter<IOperator> AnnealingOperatorParameter
+        {
+            get { return (IValueLookupParameter<IOperator>)Parameters[AnnealingOperatorName]; }
+        }
+        public IValueLookupParameter<ISimulatedAnnealingHeatingStrategy> HeatingStrategyOperatorParameter
+        {
+            get { return (IValueLookupParameter<ISimulatedAnnealingHeatingStrategy>)Parameters[HeatingStrategyOperatorName]; }
+        }
+        public ILookupParameter<BoolValue> IsAcceptedParameter
+        {
+            get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
+        }
+        public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter
+        {
+            get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
+        }
+        #endregion
+
+        [StorableConstructor]
+        protected TemperatureController(bool deserializing) : base(deserializing) { }
+        protected TemperatureController(TemperatureController original, Cloner cloner) : base(original, cloner) { }
+        public TemperatureController()
+          : base()
+        {
+            Parameters.Add(new LookupParameter<DoubleValue>(TemperatureName, "The current temperature."));
+            Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerTemperatureName, "The lower bound of the temperature."));
+            Parameters.Add(new LookupParameter<IntValue>(IterationsName, "The number of iterations."));
+            Parameters.Add(new ValueLookupParameter<IntValue>(MaximumIterationsName, "The maximum number of iterations which should be processed."));
+            Parameters.Add(new ValueLookupParameter<IOperator>(AnnealingOperatorName, "The operator that cools the temperature."));
+            Parameters.Add(new ValueLookupParameter<ISimulatedAnnealingHeatingStrategy>(HeatingStrategyOperatorName, "The operator that heats the temperature."));
+            Parameters.Add(new LookupParameter<IntValue>(TemperatureStartIndexName, "The index where the annealing or heating was last changed."));
+            Parameters.Add(new LookupParameter<BoolValue>(CoolingName, "True when the temperature should be cooled, false otherwise."));
+            Parameters.Add(new LookupParameter<DoubleValue>(StartTemperatureName, "The temperature from which cooling or reheating should occur."));
+            Parameters.Add(new LookupParameter<DoubleValue>(EndTemperatureName, "The temperature to which should be cooled or heated."));
+            Parameters.Add(new LookupParameter<BoolValue>(IsAcceptedName, "Whether the move was accepted or not."));
+            Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
+        }
+
+        public override IDeepCloneable Clone(Cloner cloner)
+        {
+            return new TemperatureController(this, cloner);
+        }
+
+        public override IOperation Apply()
+        {
+            var iterations = IterationsParameter.ActualValue.Value;
+            var heatingStrategyOperator = HeatingStrategyOperatorParameter.ActualValue;
+            var accepted = IsAcceptedParameter.ActualValue;
+
+            // if there is no heatingstrategyoperator just do cooling     
+            if (accepted == null || heatingStrategyOperator == null)
+            {
+                CoolingParameter.ActualValue.Value = true;
+            }else
+            {
+                // else, let the heatingstrategyoperator decide if it is time to reheat
+                var acceptances = AcceptanceMemoryParameter.ActualValue;
+                acceptances.Add(accepted);
+                CoolingParameter.ActualValue.Value = !heatingStrategyOperator.
+                    ShouldReheat(CoolingParameter.ActualValue.Value, acceptances);
+            }
+
+            // if we want to cool, use the cooling parameter
+            if (CoolingParameter.ActualValue.Value == true)
+            { 
+                TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, iterations - 1);
+                StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
+                EndTemperatureParameter.ActualValue.Value = LowerTemperatureParameter.ActualValue.Value;
+                return new OperationCollection {
+                    ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue),
+                    base.Apply()
+                };
+            }else
+            {
+                // else just use the heating parameter
+                return new OperationCollection {
+                    ExecutionContext.CreateOperation(HeatingStrategyOperatorParameter.ActualValue),
+                    base.Apply()
+                };
+            }
+        }
+    }
+}
