Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLab.Algorithms.SimulatedAnnealing-3.4.csproj
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLab.Algorithms.SimulatedAnnealing-3.4.csproj	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLab.Algorithms.SimulatedAnnealing-3.4.csproj	(revision 9437)
@@ -0,0 +1,220 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{9A32E619-60FB-4832-B4A2-9CF4B66C0411}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.SimulatedAnnealing</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.SimulatedAnnealing-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SimulatedAnnealing.cs" />
+    <Compile Include="SimulatedAnnealingMainLoop.cs" />
+    <Compile Include="TemperatureController.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23DA7FF4-D5B8-41B6-AA96-F0561D24F3EE}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
+      <Project>{25087811-F74C-4128-BC86-8324271DA13E}</Project>
+      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56F9106A-079F-4C61-92F6-86A84C2D84B7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102BC7D3-0EF9-439C-8F6D-96FF0FDB8E1B}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLabAlgorithmsSimulatedAnnealingPlugin.cs
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLabAlgorithmsSimulatedAnnealingPlugin.cs	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/HeuristicLabAlgorithmsSimulatedAnnealingPlugin.cs	(revision 9437)
@@ -0,0 +1,43 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Algorithms.SimulatedAnnealing plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Algorithms.SimulatedAnnealing", "3.3.5.6548")]
+  [PluginFile("HeuristicLab.Algorithms.SimulatedAnnealing-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabAlgorithmsSimulatedAnnealingPlugin : PluginBase {
+  }
+}
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Plugin.cs.frame
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Plugin.cs.frame	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Plugin.cs.frame	(revision 9437)
@@ -0,0 +1,43 @@
+#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 HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Algorithms.SimulatedAnnealing plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Algorithms.SimulatedAnnealing", "3.4.0.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.SimulatedAnnealing-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabAlgorithmsSimulatedAnnealingPlugin : PluginBase {
+  }
+}
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Properties/AssemblyInfo.cs.frame	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/Properties/AssemblyInfo.cs.frame	(revision 9437)
@@ -0,0 +1,55 @@
+﻿#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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Algorithms.SimulatedAnnealing")]
+[assembly: AssemblyDescription("HeuristicLab simulated annealing (SA)")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("0c41579a-d3c4-49fb-af7a-119eea1155ac")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.$WCREV$")]
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing - postopt.cs
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing - postopt.cs	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing - postopt.cs	(revision 9437)
@@ -0,0 +1,682 @@
+﻿#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 HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Random;
+using System;
+using System.Linq;
+
+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 HeatingOperatorName = "HeatingOperator";
+    private const string MaximumIterationsName = "MaximumIterations";
+    private const string UpperTemperatureName = "UpperTemperature";
+    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";
+    private const string ThresholdName = "Threshold";
+    private const string MemorySizeName = "MemorySize";
+    private const string PostOptimizationIterationsName = "PostOptimizationIterations";
+    private const string PostOptimizationTemperatureName = "PostOptimizationTemperature";
+    #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<IDiscreteDoubleValueModifier> HeatingOperatorParameter {
+      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[HeatingOperatorName]; }
+    }
+    private ValueParameter<DoubleRange> ThresholdParameter {
+      get { return (ValueParameter<DoubleRange>)Parameters[ThresholdName]; }
+    }
+    private ValueParameter<IntValue> MemorySizeParameter {
+      get { return (ValueParameter<IntValue>)Parameters[MemorySizeName]; }
+    }
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters[MaximumIterationsName]; }
+    }
+    private ValueParameter<DoubleValue> UpperTemperatureParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
+    }
+    private ValueParameter<DoubleValue> LowerTemperatureParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters[LowerTemperatureName]; }
+    }
+    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters[AnalyzerName]; }
+    }
+    private IValueParameter<IntValue> PostOptimizationIterationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[PostOptimizationIterationsName]; }
+    }
+    private IValueParameter<DoubleValue> PostOptimizationTemperatureParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[PostOptimizationTemperatureName]; }
+    }
+    #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 IDiscreteDoubleValueModifier HeatingOperator {
+      get { return HeatingOperatorParameter.Value; }
+      set { HeatingOperatorParameter.Value = value; }
+    }
+    public IntValue MaximumIterations {
+      get { return MaximumIterationsParameter.Value; }
+      set { MaximumIterationsParameter.Value = value; }
+    }
+    public DoubleValue UpperTemperature {
+      get { return UpperTemperatureParameter.Value; }
+      set { UpperTemperatureParameter.Value = value; }
+    }
+    public DoubleValue LowerTemperature {
+      get { return LowerTemperatureParameter.Value; }
+      set { LowerTemperatureParameter.Value = value; }
+    }
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+    public DoubleRange Threshold {
+      get { return ThresholdParameter.Value; }
+      set { ThresholdParameter.Value = value; }
+    }
+    public IntValue MemorySize {
+      get { return MemorySizeParameter.Value; }
+      set { MemorySizeParameter.Value = value; }
+    }
+    public IntValue PostOptimizationIterations {
+      get { return PostOptimizationIterationsParameter.Value; }
+      set { PostOptimizationIterationsParameter.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<IDiscreteDoubleValueModifier>(HeatingOperatorName, "The 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>(UpperTemperatureName, "The upper bound for the temperature.", new DoubleValue(100)));
+      Parameters.Add(new ValueParameter<DoubleValue>(LowerTemperatureName, "The lower bound for the temperature.", new DoubleValue(1e-5)));
+      Parameters.Add(new ValueParameter<MultiAnalyzer>(AnalyzerName, "The operator used to analyze each iteration.", new MultiAnalyzer()));
+      Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(200)));
+      Parameters.Add(new ValueParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature in case a heating operator is specified. 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.02, 0.1)));
+      Parameters.Add(new ValueParameter<IntValue>(PostOptimizationIterationsName, "Number of iterations after MaximumIterations that the search continues with a certain temperature.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<DoubleValue>(PostOptimizationTemperatureName, "The temperature that should be used for the post optimization phase, use 0 for local search.", new DoubleValue(0)));
+      PostOptimizationIterationsParameter.Hidden = true;
+      PostOptimizationTemperatureParameter.Hidden = true;
+
+      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();
+      var temperatureAssigner2 = new Assigner();
+      var maxIterationAssigner2 = new Assigner();
+      var postOptCounter = new IntCounter();
+      var postOptComparator = new Comparator();
+      var postOptBranch = new ConditionalBranch();
+      var postOptIterationsCounter = new IntCounter();
+      var postOptMainProcessor = new SubScopesProcessor();
+      var postOptMoveGenerator = new Placeholder();
+      var postOptMoveEvaluationProcessor = new SubScopesProcessor();
+      var postOptMoveEvaluator = new Placeholder();
+      var postOptEvaluatedMovesCounter = new IntCounter();
+      var postOptQualityComparator = new ProbabilisticQualityComparator();
+      var postOptAcceptsQualityBranch = new ConditionalBranch();
+      var postOptMoveMaker = new Placeholder();
+      var postOptSubScopesRemover = new SubScopesRemover();
+      var analyzer = new Placeholder();
+
+      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(0)));
+      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 = UpperTemperatureParameter.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.MemorySizeParameter.ActualName = MemorySizeParameter.Name;
+      mainLoop.ThresholdParameter.ActualName = ThresholdParameter.Name;
+      mainLoop.CoolingParameter.ActualName = CoolingName;
+      mainLoop.EndTemperatureParameter.ActualName = EndTemperatureName;
+      mainLoop.EvaluatedMovesParameter.ActualName = EvaluatedMovesName;
+      mainLoop.HeatingOperatorParameter.ActualName = HeatingOperatorParameter.Name;
+      mainLoop.IterationsParameter.ActualName = IterationsName;
+      mainLoop.LowerTemperatureParameter.ActualName = LowerTemperatureParameter.Name;
+      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;
+      mainLoop.UpperTemperatureParameter.ActualName = UpperTemperatureParameter.Name;
+      mainLoop.Successor = temperatureAssigner2;
+
+      temperatureAssigner2.Name = "Temperature := 0";
+      temperatureAssigner2.LeftSideParameter.ActualName = TemperatureName;
+      temperatureAssigner2.RightSideParameter.ActualName = PostOptimizationTemperatureParameter.Name;
+      temperatureAssigner2.Successor = maxIterationAssigner2;
+
+      maxIterationAssigner2.Name = "Prepare post-optimization phase";
+      maxIterationAssigner2.LeftSideParameter.ActualName = "TempMaxIter";
+      maxIterationAssigner2.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
+      maxIterationAssigner2.Successor = postOptCounter;
+
+      postOptCounter.Name = "MaximumIterations += PostOptimizationIterations";
+      postOptCounter.Increment = null;
+      postOptCounter.IncrementParameter.ActualName = PostOptimizationIterationsParameter.Name;
+      postOptCounter.ValueParameter.ActualName = "TempMaxIter";
+      postOptCounter.Successor = postOptComparator;
+
+      postOptComparator.Name = "Iterations >= MaximumIterations";
+      postOptComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
+      postOptComparator.LeftSideParameter.ActualName = IterationsName;
+      postOptComparator.ResultParameter.ActualName = "Terminate";
+      postOptComparator.RightSideParameter.ActualName = "TempMaxIter";
+      postOptComparator.Successor = postOptBranch;
+
+      postOptBranch.Name = "Terminate?";
+      postOptBranch.ConditionParameter.ActualName = "Terminate";
+      postOptBranch.FalseBranch = postOptIterationsCounter;
+      postOptBranch.TrueBranch = null;
+
+      postOptIterationsCounter.Name = "Iterations++";
+      postOptIterationsCounter.Increment = new IntValue(1);
+      postOptIterationsCounter.ValueParameter.ActualName = IterationsName;
+      postOptIterationsCounter.Successor = postOptMainProcessor;
+
+      postOptMainProcessor.Parallel = new BoolValue(false);
+      postOptMainProcessor.Operators.Add(postOptMoveGenerator);
+      postOptMainProcessor.Successor = postOptComparator;
+
+      postOptMoveGenerator.Name = "MoveGenerator";
+      postOptMoveGenerator.OperatorParameter.ActualName = MoveGeneratorParameter.Name;
+      postOptMoveGenerator.Successor = postOptMoveEvaluationProcessor;
+
+      postOptMoveEvaluationProcessor.Operators.Add(postOptMoveEvaluator);
+      postOptMoveEvaluationProcessor.Successor = postOptSubScopesRemover;
+
+      postOptMoveEvaluator.Name = "MoveEvaluator";
+      postOptMoveEvaluator.OperatorParameter.ActualName = MoveEvaluatorParameter.Name;
+      postOptMoveEvaluator.Successor = postOptEvaluatedMovesCounter;
+
+      postOptEvaluatedMovesCounter.Name = "EvaluatedMoves++";
+      postOptEvaluatedMovesCounter.Increment = new IntValue(1);
+      postOptEvaluatedMovesCounter.ValueParameter.ActualName = EvaluatedMovesName;
+      postOptEvaluatedMovesCounter.Successor = postOptQualityComparator;
+
+      postOptQualityComparator.Name = "Is Solution Acceptable?";
+      postOptQualityComparator.ResultParameter.ActualName = "IsAccepted";
+      postOptQualityComparator.DampeningParameter.ActualName = TemperatureName;
+      postOptQualityComparator.Successor = postOptAcceptsQualityBranch;
+
+      postOptAcceptsQualityBranch.ConditionParameter.ActualName = "IsAccepted";
+      postOptAcceptsQualityBranch.TrueBranch = postOptMoveMaker;
+      postOptAcceptsQualityBranch.Successor = null;
+      postOptAcceptsQualityBranch.FalseBranch = null;
+
+      postOptMoveMaker.Name = "MoveMaker";
+      postOptMoveMaker.OperatorParameter.ActualName = MoveMakerParameter.Name;
+      postOptMoveMaker.Successor = null;
+
+      postOptSubScopesRemover.RemoveAllSubScopes = true;
+      postOptSubScopesRemover.Successor = analyzer;
+
+      analyzer.Name = "Analyzer";
+      analyzer.OperatorParameter.ActualName = AnalyzerParameter.Name;
+      analyzer.Successor = null;
+
+      foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
+        AnnealingOperatorParameter.ValidValues.Add(op);
+        HeatingOperatorParameter.ValidValues.Add((IDiscreteDoubleValueModifier)op.Clone());
+      }
+
+      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 HeatingOperatorParameter.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 = UpperTemperatureParameter.Name;
+        op.EndValueParameter.Hidden = true;
+      }
+      #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
+
+      #region PostOptimization
+      if (Problem != null) {
+        var op = OperatorGraph.Iterate().OfType<ProbabilisticQualityComparator>().FirstOrDefault(x => x.Name == "Is Solution Acceptable?");
+        if (op == null) throw new InvalidOperationException("PostOptimizationQualityComparer not found!");
+        if (MoveEvaluator != null)
+          op.LeftSideParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+        op.RightSideParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+      }
+      #endregion
+    }
+    #endregion
+  }
+}
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing.cs
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing.cs	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealing.cs	(revision 9437)
@@ -0,0 +1,565 @@
+﻿#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.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Random;
+
+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 HeatingOperatorName = "HeatingOperator";
+    private const string MaximumIterationsName = "MaximumIterations";
+    private const string UpperTemperatureName = "UpperTemperature";
+    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";
+    private const string ThresholdName = "Threshold";
+    private const string MemorySizeName = "MemorySize";
+    #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<IDiscreteDoubleValueModifier> HeatingOperatorParameter {
+      get { return (OptionalConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters[HeatingOperatorName]; }
+    }
+    private ValueParameter<DoubleRange> ThresholdParameter {
+      get { return (ValueParameter<DoubleRange>) Parameters[ThresholdName]; }
+    }
+    private ValueParameter<IntValue> MemorySizeParameter {
+      get { return (ValueParameter<IntValue>) Parameters[MemorySizeName]; }
+    } 
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters[MaximumIterationsName]; }
+    }
+    private ValueParameter<DoubleValue> UpperTemperatureParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
+    }
+    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 IDiscreteDoubleValueModifier HeatingOperator {
+      get { return HeatingOperatorParameter.Value; }
+      set { HeatingOperatorParameter.Value = value; }
+    }
+    public IntValue MaximumIterations {
+      get { return MaximumIterationsParameter.Value; }
+      set { MaximumIterationsParameter.Value = value; }
+    }
+    public DoubleValue UpperTemperature {
+      get { return UpperTemperatureParameter.Value; }
+      set { UpperTemperatureParameter.Value = value; }
+    }
+    public DoubleValue LowerTemperature {
+      get { return LowerTemperatureParameter.Value; }
+      set { LowerTemperatureParameter.Value = value; }
+    }
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+    public DoubleRange AcceptanceThreshold {
+      get { return ThresholdParameter.Value; }
+      set { ThresholdParameter.Value = value; }
+    }
+    public IntValue AcceptanceMemorySize {
+      get { return MemorySizeParameter.Value; }
+      set { MemorySizeParameter.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<IDiscreteDoubleValueModifier>(HeatingOperatorName, "The 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>(UpperTemperatureName, "The upper bound for the 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()));
+      Parameters.Add(new ValueParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory.", new IntValue(100)));
+      Parameters.Add(new ValueParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature in case a heating operator is specified. 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.05, 0.2)));
+
+      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 = UpperTemperatureParameter.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.MemorySizeParameter.ActualName = MemorySizeParameter.Name;
+      mainLoop.ThresholdParameter.ActualName = ThresholdParameter.Name;
+      mainLoop.CoolingParameter.ActualName = CoolingName;
+      mainLoop.EndTemperatureParameter.ActualName = EndTemperatureName;
+      mainLoop.EvaluatedMovesParameter.ActualName = EvaluatedMovesName;
+      mainLoop.HeatingOperatorParameter.ActualName = HeatingOperatorParameter.Name;
+      mainLoop.IterationsParameter.ActualName = IterationsName;
+      mainLoop.LowerTemperatureParameter.ActualName = LowerTemperatureParameter.Name;
+      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;
+      mainLoop.UpperTemperatureParameter.ActualName = UpperTemperatureParameter.Name;
+
+      foreach (var op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name)) {
+        AnnealingOperatorParameter.ValidValues.Add(op);
+        HeatingOperatorParameter.ValidValues.Add((IDiscreteDoubleValueModifier)op.Clone());
+      }
+
+      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 HeatingOperatorParameter.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 = UpperTemperatureParameter.Name;
+        op.EndValueParameter.Hidden = true;
+      }
+      #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
+  }
+}
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealingMainLoop.cs
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealingMainLoop.cs	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/SimulatedAnnealingMainLoop.cs	(revision 9437)
@@ -0,0 +1,304 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+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 HeatingOperatorName = "HeatingOperator";
+    private const string MaximumIterationsName = "MaximumIterations";
+    private const string UpperTemperatureName = "UpperTemperature";
+    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 ThresholdName = "Threshold";
+    private const string MemorySizeName = "MemorySize";
+    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> UpperTemperatureParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
+    }
+    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> HeatingOperatorParameter {
+      get { return (IValueLookupParameter<IOperator>)Parameters[HeatingOperatorName]; }
+    }
+    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]; }
+    }
+    public IValueLookupParameter<DoubleRange> ThresholdParameter {
+      get { return (IValueLookupParameter<DoubleRange>)Parameters[ThresholdName]; }
+    }
+    public IValueLookupParameter<IntValue> MemorySizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MemorySizeName]; }
+    }
+    #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>(UpperTemperatureName, "The upper bound of the 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>(HeatingOperatorName, "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."));
+      Parameters.Add(new ValueLookupParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature in case a heating operator is specified. 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."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory."));
+      #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.ThresholdParameter.ActualName = ThresholdParameter.Name;
+      temperatureController.AcceptanceMemoryParameter.ActualName = AcceptanceMemoryName;
+      temperatureController.MemorySizeParameter.ActualName = MemorySizeParameter.Name;
+      temperatureController.CoolingParameter.ActualName = CoolingParameter.Name;
+      temperatureController.EndTemperatureParameter.ActualName = EndTemperatureParameter.Name;
+      temperatureController.HeatingOperatorParameter.ActualName = HeatingOperatorParameter.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;
+      temperatureController.UpperTemperatureParameter.ActualName = UpperTemperatureParameter.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();
+    }
+  }
+}
Index: /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/TemperatureController.cs
===================================================================
--- /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/TemperatureController.cs	(revision 9437)
+++ /branches/SimulatedAnnealing/HeuristicLab.Algorithms.SimulatedAnnealing/3.4/TemperatureController.cs	(revision 9437)
@@ -0,0 +1,177 @@
+﻿#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 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 HeatingOperatorName = "HeatingOperator";
+    private const string MaximumIterationsName = "MaximumIterations";
+    private const string UpperTemperatureName = "UpperTemperature";
+    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 ThresholdName = "Threshold";
+    private const string AcceptanceMemoryName = "AcceptanceMemory";
+    private const string MemorySizeName = "MemorySize";
+    #endregion
+
+    #region Parameter Properties
+    public ILookupParameter<DoubleValue> TemperatureParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[TemperatureName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperTemperatureParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperTemperatureName]; }
+    }
+    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<IOperator> HeatingOperatorParameter {
+      get { return (IValueLookupParameter<IOperator>)Parameters[HeatingOperatorName]; }
+    }
+    public ILookupParameter<BoolValue> IsAcceptedParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[IsAcceptedName]; }
+    }
+    public IValueLookupParameter<DoubleRange> ThresholdParameter {
+      get { return (IValueLookupParameter<DoubleRange>)Parameters[ThresholdName]; }
+    }
+    public ILookupParameter<ItemList<BoolValue>> AcceptanceMemoryParameter {
+      get { return (ILookupParameter<ItemList<BoolValue>>)Parameters[AcceptanceMemoryName]; }
+    }
+    public IValueLookupParameter<IntValue> MemorySizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MemorySizeName]; }
+    }
+    #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>(UpperTemperatureName, "The upper bound of the 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<IOperator>(HeatingOperatorName, "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 ValueLookupParameter<DoubleRange>(ThresholdName, "The threshold controls the temperature in case a heating operator is specified. 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."));
+      Parameters.Add(new LookupParameter<ItemList<BoolValue>>(AcceptanceMemoryName, "Memorizes the last N acceptance decisions."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MemorySizeName, "The maximum size of the acceptance memory."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TemperatureController(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var accepted = IsAcceptedParameter.ActualValue;
+      var heatingOperator = HeatingOperatorParameter.ActualValue;
+      if (accepted == null || heatingOperator == null) { // perform only annealing in case no heating operator is given
+        return new OperationCollection {
+          ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue),
+          base.Apply()
+        };
+      }
+
+      var cooling = CoolingParameter.ActualValue.Value;
+      var iterations = IterationsParameter.ActualValue.Value;
+      var ratioStart = ThresholdParameter.ActualValue.Start;
+      var ratioEnd = ThresholdParameter.ActualValue.End;
+
+      var acceptances = AcceptanceMemoryParameter.ActualValue;
+      acceptances.Add(new BoolValue(accepted.Value));
+      if (acceptances.Count > MemorySizeParameter.ActualValue.Value) acceptances.RemoveAt(0);
+      var ratio = acceptances.Average(x => x.Value ? 1.0 : 0.0);
+      
+
+      if (!cooling && ratio >= ratioEnd) { // temperature is heated, but should be cooled
+        cooling = true;
+        TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, iterations - 1);
+        StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
+        EndTemperatureParameter.ActualValue.Value = LowerTemperatureParameter.ActualValue.Value;
+      } else if (cooling && ratio <= ratioStart) {  // temperature is cooled, but should be heated
+        cooling = false;
+        TemperatureStartIndexParameter.ActualValue.Value = Math.Max(0, iterations - 1);
+        StartTemperatureParameter.ActualValue.Value = TemperatureParameter.ActualValue.Value;
+        EndTemperatureParameter.ActualValue.Value = UpperTemperatureParameter.ActualValue.Value;
+      }
+
+      CoolingParameter.ActualValue.Value = cooling;
+
+      if (cooling) {
+        return new OperationCollection {
+          ExecutionContext.CreateOperation(AnnealingOperatorParameter.ActualValue),
+          base.Apply()
+        };
+      }
+      // heating
+      return new OperationCollection {
+        ExecutionContext.CreateOperation(HeatingOperatorParameter.ActualValue),
+        base.Apply()
+      };
+    }
+  }
+}
