Index: /trunk/sources/HeuristicLab 3.3.sln
===================================================================
--- /trunk/sources/HeuristicLab 3.3.sln	(revision 5752)
+++ /trunk/sources/HeuristicLab 3.3.sln	(revision 5753)
@@ -330,4 +330,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3", "HeuristicLab.Algorithms.ParticleSwarmOptimization\3.3\HeuristicLab.Algorithms.ParticleSwarmOptimization-3.3.csproj", "{2C429157-9C34-4DD3-9D5F-B444B751E39A}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3", "HeuristicLab.Algorithms.VariableNeighborhoodSearch\3.3\HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj", "{E4CFB0C3-0589-4893-B38E-8BEDF885C765}"
 EndProject
 Global
@@ -1496,4 +1498,16 @@
 		{2C429157-9C34-4DD3-9D5F-B444B751E39A}.Release|x86.ActiveCfg = Release|x86
 		{2C429157-9C34-4DD3-9D5F-B444B751E39A}.Release|x86.Build.0 = Release|x86
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|x64.ActiveCfg = Debug|x64
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|x64.Build.0 = Debug|x64
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|x86.ActiveCfg = Debug|x86
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Debug|x86.Build.0 = Debug|x86
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|x64.ActiveCfg = Release|x64
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|x64.Build.0 = Release|x64
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|x86.ActiveCfg = Release|x86
+		{E4CFB0C3-0589-4893-B38E-8BEDF885C765}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/HeuristicLab.Algorithms.LocalSearch-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/HeuristicLab.Algorithms.LocalSearch-3.3.csproj	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/HeuristicLab.Algorithms.LocalSearch-3.3.csproj	(revision 5753)
@@ -12,5 +12,6 @@
     <AssemblyName>HeuristicLab.Algorithms.LocalSearch-3.3</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
     <SignAssembly>true</SignAssembly>
@@ -107,4 +108,5 @@
   <ItemGroup>
     <Compile Include="HeuristicLabAlgorithmsLocalSearchPlugin.cs" />
+    <Compile Include="LocalSearchImprovementOperator.cs" />
     <Compile Include="LocalSearchMainLoop.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs	(revision 5753)
@@ -168,4 +168,6 @@
       variableCreator.Name = "Initialize EvaluatedMoves";
       variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedMoves", new IntValue()));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(0)));
       variableCreator.Successor = resultsCollector;
 
@@ -182,4 +184,6 @@
       mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
       mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
+      mainLoop.IterationsParameter.ActualName = "Iterations";
+      mainLoop.BestQualityParameter.ActualName = "BestQuality";
 
       moveQualityAnalyzer = new BestAverageWorstQualityAnalyzer();
Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs	(revision 5753)
@@ -0,0 +1,306 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Algorithms.LocalSearch;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Analysis;
+
+namespace HeuristicLab.Algorithms.LocalSearch {
+  /// <summary>
+  /// A local search improvement operator.
+  /// </summary>
+  [Item("LocalSearchImprovementOperator", "A local search improvement operator.")]
+  [StorableClass]
+  public class LocalSearchImprovementOperator: SingleSuccessorOperator, ILocalImprovementOperator {
+    [Storable]
+    private LocalSearchMainLoop loop;
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+    
+    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
+      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
+    }
+    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
+      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
+    }
+    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
+      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
+    }
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private ValueParameter<IntValue> SampleSizeParameter {
+      get { return (ValueParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+    public LookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+
+    public IMoveGenerator 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 MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected LocalSearchImprovementOperator(bool deserializing) : base(deserializing) {}
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+    protected LocalSearchImprovementOperator(LocalSearchImprovementOperator original, Cloner cloner)
+      : base(original, cloner) {
+        this.loop = cloner.Clone(original.loop);
+        this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+        Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LocalSearchImprovementOperator(this, cloner);
+    }
+    public LocalSearchImprovementOperator()
+      : base() {
+        loop = new LocalSearchMainLoop();
+        
+        ResultsCollector rc = (loop.OperatorGraph.InitialOperator as SingleSuccessorOperator).Successor as ResultsCollector;
+        rc.CollectedValues.Remove("BestLocalQuality");
+
+        qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+
+        Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
+        Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
+        Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
+        Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
+        Parameters.Add(new ValueParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(1500)));
+        Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
+        Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution.", new MultiAnalyzer()));
+
+        Initialize();
+    }
+
+    private void Initialize() {
+      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
+    }
+
+    public void OnProblemChanged(IProblem problem) {
+      UpdateMoveOperators(problem);
+      ChooseMoveOperators();
+
+      ParameterizeMoveGenerators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveEvaluators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveMakers(problem as ISingleObjectiveProblem);
+
+      ParameterizeAnalyzers(problem as ISingleObjectiveProblem);
+      UpdateAnalyzers(problem as ISingleObjectiveProblem);
+    }
+
+    void ParameterizeAnalyzers(ISingleObjectiveProblem problem) {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      if (problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
+        if (MoveEvaluator != null)
+          qualityAnalyzer.QualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
+      }
+    }
+
+    void UpdateAnalyzers(ISingleObjectiveProblem problem) {
+      Analyzer.Operators.Clear();
+      if (problem != null) {
+        foreach (IAnalyzer analyzer in problem.Operators.OfType<IAnalyzer>()) {
+          IAnalyzer clone = analyzer.Clone() as IAnalyzer;
+          foreach (IScopeTreeLookupParameter param in clone.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 0;
+          Analyzer.Operators.Add(clone);
+        }
+      }
+      Analyzer.Operators.Add(qualityAnalyzer);
+    }
+
+    void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
+      ChooseMoveOperators();
+    }
+
+    private void UpdateMoveOperators(IProblem problem) {
+      IMoveGenerator oldMoveGenerator = MoveGenerator;
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      ClearMoveParameters();
+
+      if (problem != null) {
+        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+
+        foreach (IMoveMaker maker in problem.Operators.OfType<IMoveMaker>().OrderBy(x => x.Name))
+          MoveMakerParameter.ValidValues.Add(maker);
+
+        foreach (ISingleObjectiveMoveEvaluator evaluator in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(x => x.Name))
+          MoveEvaluatorParameter.ValidValues.Add(evaluator);
+      }
+
+      if (oldMoveGenerator != null) {
+        IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+      }
+      if (MoveGenerator == null) {
+        ClearMoveParameters();
+      }
+
+      if (oldMoveMaker != null) {
+        IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+        if (mm != null) MoveMaker = mm;
+      }
+
+      if (oldMoveEvaluator != null) {
+        ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+        if (me != null) MoveEvaluator = me;
+      }
+    }
+
+    private void ChooseMoveOperators() {
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      if (MoveGenerator != null) {
+        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+        foreach (Type type in moveTypes.ToList()) {
+          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+            moveTypes.Remove(type);
+        }
+        List<IMoveMaker> validMoveMakers = new List<IMoveMaker>();
+        List<ISingleObjectiveMoveEvaluator> validMoveEvaluators = new List<ISingleObjectiveMoveEvaluator>();
+
+        foreach (Type type in moveTypes) {
+          var moveMakers = MoveMakerParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (IMoveMaker moveMaker in moveMakers)
+            validMoveMakers.Add(moveMaker);
+
+          var moveEvaluators = MoveEvaluatorParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (ISingleObjectiveMoveEvaluator moveEvaluator in moveEvaluators)
+            validMoveEvaluators.Add(moveEvaluator);
+        }
+        if (oldMoveMaker != null) {
+          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+          if (mm != null) MoveMaker = mm;
+          else MoveMaker = validMoveMakers.FirstOrDefault();
+        } 
+
+        if (oldMoveEvaluator != null) {
+          ISingleObjectiveMoveEvaluator me = validMoveEvaluators.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+          if (me != null) MoveEvaluator = me;
+          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
+        } 
+      }
+    }
+
+    private void ClearMoveParameters() {
+      MoveGeneratorParameter.ValidValues.Clear();
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
+    }
+
+    private void ParameterizeMoveGenerators(ISingleObjectiveProblem problem) {
+      if (problem != null) {
+        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
+          generator.SampleSizeParameter.ActualName = SampleSizeParameter.Name;
+      }
+    }
+    private void ParameterizeMoveEvaluators(ISingleObjectiveProblem problem) {
+      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+      }
+    }
+    private void ParameterizeMoveMakers(ISingleObjectiveProblem problem) {
+      foreach (IMoveMaker op in problem.Operators.OfType<IMoveMaker>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+        if (MoveEvaluator != null)
+          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
+    }
+
+    public override IOperation Apply() {
+      Scope subScope = new Scope();
+      Scope individual = new Scope();
+
+      foreach (Variable var in ExecutionContext.Scope.Variables) {
+        individual.Variables.Add(var);
+      }
+      subScope.SubScopes.Add(individual);
+
+      ExecutionContext.Scope.SubScopes.Add(subScope);
+      int index = subScope.Parent.SubScopes.IndexOf(subScope);
+
+      SubScopesProcessor processor = new SubScopesProcessor();
+      SubScopesRemover remover = new SubScopesRemover();
+
+      remover.RemoveAllSubScopes = false;
+      remover.SubScopeIndexParameter.Value = new IntValue(index);
+
+      for (int i = 0; i < index; i++) {
+        processor.Operators.Add(new EmptyOperator());
+      }
+
+      VariableCreator variableCreator = new VariableCreator();
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("LocalIterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestLocalQuality", new DoubleValue(0)));
+
+      variableCreator.Successor = loop;
+
+      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
+
+      processor.Operators.Add(variableCreator);
+      processor.Successor = remover;
+
+      IOperation next = base.Apply();
+      if (next as ExecutionContext != null) {
+        remover.Successor = (next as ExecutionContext).Operator;
+      }
+
+      return ExecutionContext.CreateChildOperation(processor);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs	(revision 5753)
@@ -46,4 +46,7 @@
       get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
+    public LookupParameter<DoubleValue> BestQualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["BestLocalQuality"]; }
+    }
     public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
       get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
@@ -51,4 +54,7 @@
     public LookupParameter<DoubleValue> MoveQualityParameter {
       get { return (LookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public LookupParameter<IntValue> IterationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["LocalIterations"]; }
     }
     public ValueLookupParameter<IntValue> MaximumIterationsParameter {
@@ -79,5 +85,5 @@
     public LocalSearchMainLoop()
       : base() {
-      Initialize();
+        Initialize();
     }
     private LocalSearchMainLoop(LocalSearchMainLoop original, Cloner cloner)
@@ -93,6 +99,8 @@
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
       Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new LookupParameter<DoubleValue>("BestLocalQuality", "The value which represents the best quality found so far."));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The value which represents the quality of a move."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of generations."));
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
       Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
@@ -107,5 +115,4 @@
 
       #region Create operators
-      VariableCreator variableCreator = new VariableCreator();
       SubScopesProcessor subScopesProcessor0 = new SubScopesProcessor();
       Assigner bestQualityInitializer = new Assigner();
@@ -124,4 +131,5 @@
       Placeholder moveMaker = new Placeholder();
       Assigner bestQualityUpdater = new Assigner();
+      ResultsCollector resultsCollector2 = new ResultsCollector();
       MergingReducer mergingReducer = new MergingReducer();
       Placeholder analyzer2 = new Placeholder();
@@ -131,9 +139,6 @@
       ConditionalBranch iterationsTermination = new ConditionalBranch();
 
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0))); // Class LocalSearch expects this to be called Iterations
-      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(0)));
-
       bestQualityInitializer.Name = "Initialize BestQuality";
-      bestQualityInitializer.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityInitializer.LeftSideParameter.ActualName = BestQualityParameter.Name;
       bestQualityInitializer.RightSideParameter.ActualName = QualityParameter.Name;
 
@@ -142,6 +147,6 @@
 
       resultsCollector1.CopyValue = new BoolValue(false);
-      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
-      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Quality", null, "BestQuality"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>(IterationsParameter.Name));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>(BestQualityParameter.Name, null, BestQualityParameter.Name));
       resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
 
@@ -172,6 +177,10 @@
 
       bestQualityUpdater.Name = "Update BestQuality";
-      bestQualityUpdater.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityUpdater.LeftSideParameter.ActualName = BestQualityParameter.Name;
       bestQualityUpdater.RightSideParameter.ActualName = QualityParameter.Name;
+
+      resultsCollector2.CopyValue = new BoolValue(false);
+      resultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>(BestQualityParameter.Name, null, BestQualityParameter.Name));
+      resultsCollector2.ResultsParameter.ActualName = ResultsParameter.Name;
 
       analyzer2.Name = "Analyzer (placeholder)";
@@ -182,9 +191,9 @@
       iterationsCounter.Name = "Iterations Counter";
       iterationsCounter.Increment = new IntValue(1);
-      iterationsCounter.ValueParameter.ActualName = "Iterations";
+      iterationsCounter.ValueParameter.ActualName = IterationsParameter.Name;
 
       iterationsComparator.Name = "Iterations >= MaximumIterations";
       iterationsComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
-      iterationsComparator.LeftSideParameter.ActualName = "Iterations";
+      iterationsComparator.LeftSideParameter.ActualName = IterationsParameter.Name;
       iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
       iterationsComparator.ResultParameter.ActualName = "Terminate";
@@ -195,6 +204,5 @@
 
       #region Create operator graph
-      OperatorGraph.InitialOperator = variableCreator;
-      variableCreator.Successor = subScopesProcessor0;
+      OperatorGraph.InitialOperator = subScopesProcessor0;
       subScopesProcessor0.Operators.Add(bestQualityInitializer);
       subScopesProcessor0.Successor = resultsCollector1;
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/HeuristicLab.Algorithms.SimulatedAnnealing-3.3.csproj	(revision 5753)
@@ -12,5 +12,6 @@
     <AssemblyName>HeuristicLab.Algorithms.SimulatedAnnealing-3.3</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
     <SignAssembly>true</SignAssembly>
@@ -107,4 +108,5 @@
   <ItemGroup>
     <Compile Include="HeuristicLabAlgorithmsSimulatedAnnealingPlugin.cs" />
+    <Compile Include="SimulatedAnnealingImprovementOperator.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="SimulatedAnnealing.cs" />
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealing.cs	(revision 5753)
@@ -189,4 +189,5 @@
       variableCreator.Name = "Initialize EvaluatedMoves";
       variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedMoves", new IntValue()));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
       variableCreator.Successor = resultsCollector;
 
@@ -206,4 +207,5 @@
       mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
       mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
+      mainLoop.IterationsParameter.ActualName = "Iterations";
 
       foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs	(revision 5753)
@@ -0,0 +1,331 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Algorithms.SimulatedAnnealing;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Analysis;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.SimulatedAnnealing {
+  /// <summary>
+  /// A simulated annealing improvement operator.
+  /// </summary>
+  [Item("SimulatedAnnealingImprovementOperator", "A simulated annealing improvement operator.")]
+  [StorableClass]
+  public class SimulatedAnnealingImprovementOperator: SingleSuccessorOperator, ILocalImprovementOperator {
+    [Storable]
+    private SimulatedAnnealingMainLoop loop;
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+    
+    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
+      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
+    }
+    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
+      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
+    }
+    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
+      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
+    }
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private ValueParameter<IntValue> InnerIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["InnerIterations"]; }
+    }
+    public LookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    private ValueParameter<DoubleValue> StartTemperatureParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["StartTemperature"]; }
+    }
+    private ValueParameter<DoubleValue> EndTemperatureParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["EndTemperature"]; }
+    }
+    private ConstrainedValueParameter<IDiscreteDoubleValueModifier> AnnealingOperatorParameter {
+      get { return (ConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["AnnealingOperator"]; }
+    }
+
+    public IMoveGenerator 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 MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected SimulatedAnnealingImprovementOperator(bool deserializing) : base(deserializing) {}
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
+    protected SimulatedAnnealingImprovementOperator(SimulatedAnnealingImprovementOperator original, Cloner cloner)
+      : base(original, cloner) {
+        this.loop = cloner.Clone(original.loop);
+        this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+        Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimulatedAnnealingImprovementOperator(this, cloner);
+    }
+    public SimulatedAnnealingImprovementOperator()
+      : base() {
+        loop = new SimulatedAnnealingMainLoop();
+
+        qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+
+        Parameters.Add(new ConstrainedValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
+        Parameters.Add(new ConstrainedValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
+        Parameters.Add(new ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
+        Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
+        Parameters.Add(new ValueParameter<IntValue>("InnerIterations", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(1500)));
+        Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
+        Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution.", new MultiAnalyzer()));
+        Parameters.Add(new ValueParameter<DoubleValue>("StartTemperature", "The initial temperature.", new DoubleValue(100)));
+        Parameters.Add(new ValueParameter<DoubleValue>("EndTemperature", "The final temperature which should be reached when iterations reaches maximum iterations.", new DoubleValue(1e-6)));
+        Parameters.Add(new ConstrainedValueParameter<IDiscreteDoubleValueModifier>("AnnealingOperator", "The operator used to modify the temperature."));
+
+        foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
+          AnnealingOperatorParameter.ValidValues.Add(op);
+
+        ParameterizeAnnealingOperators();
+
+        Initialize();
+    }
+
+    private void Initialize() {
+      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
+    }
+
+    private void ParameterizeAnnealingOperators() {
+      foreach (IDiscreteDoubleValueModifier op in AnnealingOperatorParameter.ValidValues) {
+        op.IndexParameter.ActualName = "LocalIterations";
+        op.StartIndexParameter.Value = new IntValue(0);
+        op.EndIndexParameter.ActualName = MaximumIterationsParameter.Name;
+        op.ValueParameter.ActualName = "Temperature";
+        op.StartValueParameter.ActualName = StartTemperatureParameter.Name;
+        op.EndValueParameter.ActualName = EndTemperatureParameter.Name;
+      }
+    }
+
+    public void OnProblemChanged(IProblem problem) {
+      UpdateMoveOperators(problem);
+      ChooseMoveOperators();
+
+      ParameterizeMoveGenerators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveEvaluators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveMakers(problem as ISingleObjectiveProblem);
+
+      ParameterizeAnalyzers(problem as ISingleObjectiveProblem);
+      UpdateAnalyzers(problem as ISingleObjectiveProblem);
+    }
+
+    void ParameterizeAnalyzers(ISingleObjectiveProblem problem) {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      if (problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
+        qualityAnalyzer.QualityParameter.ActualName = problem.Evaluator.QualityParameter.Name;
+        qualityAnalyzer.QualityParameter.Depth = 0;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
+      }
+    }
+
+    void UpdateAnalyzers(ISingleObjectiveProblem problem) {
+      Analyzer.Operators.Clear();
+      if (problem != null) {
+        foreach (IAnalyzer analyzer in problem.Operators.OfType<IAnalyzer>()) {
+          IAnalyzer clone = analyzer.Clone() as IAnalyzer;
+          foreach (IScopeTreeLookupParameter param in clone.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 0;
+          Analyzer.Operators.Add(clone);
+        }
+      }
+      Analyzer.Operators.Add(qualityAnalyzer);
+    }
+
+    void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
+      ChooseMoveOperators();
+    }
+
+    private void UpdateMoveOperators(IProblem problem) {
+      IMoveGenerator oldMoveGenerator = MoveGenerator;
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      ClearMoveParameters();
+
+      if (problem != null) {
+        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+
+        foreach (IMoveMaker maker in problem.Operators.OfType<IMoveMaker>().OrderBy(x => x.Name))
+          MoveMakerParameter.ValidValues.Add(maker);
+
+        foreach (ISingleObjectiveMoveEvaluator evaluator in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(x => x.Name))
+          MoveEvaluatorParameter.ValidValues.Add(evaluator);
+      }
+
+      if (oldMoveGenerator != null) {
+        IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+      }
+      if (MoveGenerator == null) {
+        ClearMoveParameters();
+      }
+
+      if (oldMoveMaker != null) {
+        IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+        if (mm != null) MoveMaker = mm;
+      }
+
+      if (oldMoveEvaluator != null) {
+        ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+        if (me != null) MoveEvaluator = me;
+      }
+    }
+
+    private void ChooseMoveOperators() {
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      if (MoveGenerator != null) {
+        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+        foreach (Type type in moveTypes.ToList()) {
+          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+            moveTypes.Remove(type);
+        }
+        List<IMoveMaker> validMoveMakers = new List<IMoveMaker>();
+        List<ISingleObjectiveMoveEvaluator> validMoveEvaluators = new List<ISingleObjectiveMoveEvaluator>();
+
+        foreach (Type type in moveTypes) {
+          var moveMakers = MoveMakerParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (IMoveMaker moveMaker in moveMakers)
+            validMoveMakers.Add(moveMaker);
+
+          var moveEvaluators = MoveEvaluatorParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (ISingleObjectiveMoveEvaluator moveEvaluator in moveEvaluators)
+            validMoveEvaluators.Add(moveEvaluator);
+        }
+        if (oldMoveMaker != null) {
+          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+          if (mm != null) MoveMaker = mm;
+          else MoveMaker = validMoveMakers.FirstOrDefault();
+        } 
+
+        if (oldMoveEvaluator != null) {
+          ISingleObjectiveMoveEvaluator me = validMoveEvaluators.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+          if (me != null) MoveEvaluator = me;
+          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
+        } 
+      }
+    }
+
+    private void ClearMoveParameters() {
+      MoveGeneratorParameter.ValidValues.Clear();
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
+    }
+
+    private void ParameterizeMoveGenerators(ISingleObjectiveProblem problem) {
+      if (problem != null) {
+        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
+          generator.SampleSizeParameter.ActualName = InnerIterationsParameter.Name;
+      }
+    }
+    private void ParameterizeMoveEvaluators(ISingleObjectiveProblem problem) {
+      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+      }
+    }
+    private void ParameterizeMoveMakers(ISingleObjectiveProblem problem) {
+      foreach (IMoveMaker op in problem.Operators.OfType<IMoveMaker>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+        if (MoveEvaluator != null)
+          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
+    }
+
+    public override IOperation Apply() {
+      Scope subScope = new Scope();
+      Scope individual = new Scope();
+
+      foreach (Variable var in ExecutionContext.Scope.Variables) {
+        individual.Variables.Add(var);
+      }
+      subScope.SubScopes.Add(individual);
+
+      ExecutionContext.Scope.SubScopes.Add(subScope);
+      int index = subScope.Parent.SubScopes.IndexOf(subScope);
+
+      SubScopesProcessor processor = new SubScopesProcessor();
+      SubScopesRemover remover = new SubScopesRemover();
+
+      remover.RemoveAllSubScopes = false;
+      remover.SubScopeIndexParameter.Value = new IntValue(index);
+
+      for (int i = 0; i < index; i++) {
+        processor.Operators.Add(new EmptyOperator());
+      }
+
+      VariableCreator variableCreator = new VariableCreator();
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("LocalIterations", new IntValue(0)));
+
+      variableCreator.Successor = loop;
+
+      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
+
+      processor.Operators.Add(variableCreator);
+      processor.Successor = remover;
+
+      IOperation next = base.Apply();
+      if (next as ExecutionContext != null) {
+        remover.Successor = (next as ExecutionContext).Operator;
+      }
+
+      return ExecutionContext.CreateChildOperation(processor);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 5752)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 5753)
@@ -60,4 +60,7 @@
       get { return (ValueLookupParameter<IntValue>)Parameters["InnerIterations"]; }
     }
+    public LookupParameter<IntValue> IterationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["LocalIterations"]; }
+    }
     public ValueLookupParameter<IntValue> MaximumIterationsParameter {
       get { return (ValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
@@ -109,4 +112,5 @@
       Parameters.Add(new ValueLookupParameter<DoubleValue>("EndTemperature", "The end temperature."));
       Parameters.Add(new ValueLookupParameter<IntValue>("InnerIterations", "The amount of inner iterations (number of moves before temperature is adjusted again)."));
+      Parameters.Add(new LookupParameter<IntValue>("LocalIterations", "The number of generations."));
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations which should be processed."));
 
@@ -144,8 +148,7 @@
       ConditionalBranch iterationsTermination = new ConditionalBranch();
 
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0))); // Class SimulatedAnnealing expects this to be called Iterations
       variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("Temperature", new DoubleValue(double.MaxValue)));
 
-      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>(IterationsParameter.Name));
       resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Temperature"));
       resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
@@ -180,8 +183,8 @@
       iterationsCounter.Name = "Increment Iterations";
       iterationsCounter.Increment = new IntValue(1);
-      iterationsCounter.ValueParameter.ActualName = "Iterations";
+      iterationsCounter.ValueParameter.ActualName = IterationsParameter.Name;
 
       iterationsComparator.Name = "Iterations >= MaximumIterations";
-      iterationsComparator.LeftSideParameter.ActualName = "Iterations";
+      iterationsComparator.LeftSideParameter.ActualName = IterationsParameter.Name;
       iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
       iterationsComparator.ResultParameter.ActualName = "Terminate";
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj	(revision 5753)
@@ -0,0 +1,213 @@
+﻿<?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>{E4CFB0C3-0589-4893-B38E-8BEDF885C765}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.VariableNeighborhoodSearch</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3</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>bin\Debug\</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>bin\Release\</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>bin\x64\Debug\</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>bin\x64\Release\</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>bin\x86\Debug\</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>bin\x86\Release\</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.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <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="HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs" />
+    <Compile Include="IShakingOperator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperator.cs" />
+    <Compile Include="VariableNeighborhoodSearch.cs" />
+    <Compile Include="VariableNeighborhoodSearchMainLoop.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Algorithms.LocalSearch\3.3\HeuristicLab.Algorithms.LocalSearch-3.3.csproj">
+      <Project>{4AE3FC69-C575-42D2-BC46-0FAD5850EFC5}</Project>
+      <Name>HeuristicLab.Algorithms.LocalSearch-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </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>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Selection\3.3\HeuristicLab.Selection-3.3.csproj">
+      <Project>{2C36CD4F-E5F5-43A4-801A-201EA895FE17}</Project>
+      <Name>HeuristicLab.Selection-3.3</Name>
+    </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>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25\HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs"</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame	(revision 5753)
@@ -0,0 +1,44 @@
+#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.VariableNeighborhoodSearch {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Algorithms.VariableNeighborhoodSearch plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Algorithms.VariableNeighborhoodSearch", "3.3.3.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.VariableNeighborhoodSearch-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")]
+  [PluginDependency("HeuristicLab.Selection", "3.3")]
+  public class HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin : PluginBase {
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs	(revision 5753)
@@ -0,0 +1,33 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Optimization;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  public interface IShakingOperator: IManipulator {
+    void OnProblemChanged(IProblem problem);
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/Properties/AssemblyInfo.frame
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/Properties/AssemblyInfo.frame	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/Properties/AssemblyInfo.frame	(revision 5753)
@@ -0,0 +1,55 @@
+﻿#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 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.VariableNeighborhoodSearch")]
+[assembly: AssemblyDescription("HeuristicLab variable neighborhood search (VNS)")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 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("0D4DB694-8D3E-4238-AA50-31E30D158BA7")]
+
+// 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.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.3.$WCREV$")]
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 5753)
@@ -0,0 +1,93 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("ShakingOperator", "A shaking operator for VNS.")]
+  [StorableClass]
+  public class ShakingOperator<T> : CheckedMultiOperator<T>, IShakingOperator where T : class, IManipulator {
+    public IValueLookupParameter<IntValue> IndexParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["Index"]; }
+    }
+    
+    public ILookupParameter<BoolValue> ContinueParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Continue"]; }
+    }
+        
+    [StorableConstructor]
+    protected ShakingOperator(bool deserializing) : base(deserializing) { }
+    protected ShakingOperator(ShakingOperator<T> original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShakingOperator<T>(this, cloner);
+    }
+    public ShakingOperator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("Index", "The index of the operator that should be applied (k)."));
+      Parameters.Add(new LookupParameter<BoolValue>("Continue", "True if k <= available operators."));
+    }
+
+    public void OnProblemChanged(IProblem problem) {
+      Operators.Clear();
+
+      if (problem != null) {
+        foreach (T manipulator in problem.Operators.OfType<T>().OrderBy(x => x.Name))
+          Operators.Add(manipulator);
+      }
+    }
+
+    public override IOperation Apply() {
+      int index = IndexParameter.ActualValue.Value;    
+      var operators = base.Operators.CheckedItems.ToList();
+
+      IOperator successor = null;
+
+      if (index >= operators.Count - 1) {
+        ContinueParameter.ActualValue = new BoolValue(false);
+      } else {
+        ContinueParameter.ActualValue = new BoolValue(true);
+      }
+
+      if (index >= 0 && index < operators.Count) {
+        successor = operators[index].Value;
+      }
+
+      OperationCollection next = new OperationCollection(base.Apply());
+      if (successor != null)
+        next.Insert(0, ExecutionContext.CreateOperation(successor));
+
+      return next;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs	(revision 5753)
@@ -0,0 +1,297 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Analysis;
+using HeuristicLab.Random;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Operators;
+using HeuristicLab.Algorithms.LocalSearch;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  [Item("Variable Neighborhood Search", "A variable neighborhood search algorithm.")]
+  [Creatable("Algorithms")]
+  [StorableClass]
+  public sealed class VariableNeighborhoodSearch : EngineAlgorithm, IStorableContent {
+    public string Filename { get; set; }
+
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(ISingleObjectiveProblem); }
+    }
+    public new ISingleObjectiveProblem Problem {
+      get { return (ISingleObjectiveProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private ValueParameter<IntValue> SeedParameter {
+      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
+    }
+    private ValueParameter<ILocalImprovementOperator> LocalImprovementParameter {
+      get { return (ValueParameter<ILocalImprovementOperator>)Parameters["LocalImprovement"]; }
+    }
+    private ValueParameter<IShakingOperator> ShakingParameter {
+      get { return (ValueParameter<IShakingOperator>)Parameters["Shaking"]; }
+    }
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    private VariableNeighborhoodSearchMainLoop VNSMainLoop {
+      get { return FindMainLoop(SolutionsCreator.Successor); }
+    }
+    #endregion
+
+    #region Properties
+    private RandomCreator RandomCreator {
+      get { return (RandomCreator)OperatorGraph.InitialOperator; }
+    }
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
+    private SolutionsCreator SolutionsCreator {
+      get { return (SolutionsCreator)RandomCreator.Successor; }
+    }
+    #endregion
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+
+    [StorableConstructor]
+    private VariableNeighborhoodSearch(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+
+    }
+    private VariableNeighborhoodSearch(VariableNeighborhoodSearch original, Cloner cloner)
+      : base(original, cloner) {
+      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+      Initialize();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableNeighborhoodSearch(this, cloner);
+    }
+    public VariableNeighborhoodSearch()
+      : base() {
+      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new ValueParameter<ILocalImprovementOperator>("LocalImprovement", "The local improvement operation", new LocalSearchImprovementOperator()));
+      Parameters.Add(new ValueParameter<IShakingOperator>("Shaking", "The shaking operation"));
+      Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(1000)));
+      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
+
+      RandomCreator randomCreator = new RandomCreator();
+      SolutionsCreator solutionsCreator = new SolutionsCreator();
+      VariableCreator variableCreator = new VariableCreator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+      VariableNeighborhoodSearchMainLoop mainLoop = new VariableNeighborhoodSearchMainLoop();
+      OperatorGraph.InitialOperator = randomCreator;
+
+      randomCreator.RandomParameter.ActualName = "Random";
+      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
+      randomCreator.SeedParameter.Value = null;
+      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
+      randomCreator.SetSeedRandomlyParameter.Value = null;
+      randomCreator.Successor = solutionsCreator;
+
+      solutionsCreator.NumberOfSolutions = new IntValue(1);
+      solutionsCreator.Successor = variableCreator;
+
+      variableCreator.Name = "Initialize Evaluated Solutions";
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue()));
+      variableCreator.Successor = resultsCollector;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
+      resultsCollector.ResultsParameter.ActualName = "Results";
+      resultsCollector.Successor = mainLoop;
+
+      mainLoop.LocalImprovementParameter.ActualName = LocalImprovementParameter.Name;
+      mainLoop.ShakingParameter.ActualName = ShakingParameter.Name;
+      mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+      mainLoop.ResultsParameter.ActualName = "Results";
+      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+      mainLoop.EvaluatedSolutionsParameter.ActualName = "EvaluatedSolutions";
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      ParameterizeAnalyzers();
+      UpdateAnalyzers();
+
+      Initialize();
+    }
+
+    public override void Prepare() {
+      if (Problem != null) base.Prepare();
+    }
+
+    private void Initialize() {
+      if (Problem != null) {
+        Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      }
+      LocalImprovementParameter.ValueChanged += new EventHandler(LocalImprovementParameter_ValueChanged);
+    }
+
+    #region Events
+    protected override void OnProblemChanged() {
+      ParameterizeStochasticOperator(Problem.SolutionCreator);
+      ParameterizeStochasticOperator(Problem.Evaluator);
+      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
+      ParameterizeSolutionsCreator();
+      ParameterizeVNSMainLoop();
+      ParameterizeAnalyzers();
+      ParameterizeIterationBasedOperators();
+      UpdateShakingOperator();
+      UpdateLocalImprovementOperator();
+      UpdateAnalyzers();
+      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      base.OnProblemChanged();
+    }
+
+    protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
+      ParameterizeStochasticOperator(Problem.SolutionCreator);
+      ParameterizeSolutionsCreator();
+      base.Problem_SolutionCreatorChanged(sender, e);
+    }
+    protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
+      ParameterizeStochasticOperator(Problem.Evaluator);
+      ParameterizeSolutionsCreator();
+      ParameterizeVNSMainLoop();
+      ParameterizeAnalyzers();
+      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      base.Problem_EvaluatorChanged(sender, e);
+    }
+    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
+      ParameterizeIterationBasedOperators();
+      UpdateShakingOperator();
+      UpdateLocalImprovementOperator();
+      UpdateAnalyzers();
+      base.Problem_OperatorsChanged(sender, e);
+    }
+
+    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeVNSMainLoop();
+      ParameterizeAnalyzers();
+    }
+
+    void LocalImprovementParameter_ValueChanged(object sender, EventArgs e) {
+      if (LocalImprovementParameter.Value != null)
+        LocalImprovementParameter.Value.OnProblemChanged(Problem);
+    }
+    #endregion
+
+    #region Helpers
+    private void ParameterizeSolutionsCreator() {
+      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+    }
+    private void ParameterizeStochasticOperator(IOperator op) {
+      if (op is IStochasticOperator)
+        ((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+    }
+    private void ParameterizeVNSMainLoop() {
+      VNSMainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      VNSMainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+      VNSMainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+    }
+    private void ParameterizeAnalyzers() {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      if (Problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+        qualityAnalyzer.QualityParameter.Depth = 1;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
+      }
+    }
+    private void ParameterizeIterationBasedOperators() {
+      if (Problem != null) {
+        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
+          op.IterationsParameter.ActualName = "Iterations";
+          op.MaximumIterationsParameter.ActualName = "MaximumIterations";
+        }
+      }
+    }
+    private void UpdateShakingOperator() {
+      Type manipulatorType = typeof(IManipulator);
+      List<Type> manipulatorInterfaces = new List<Type>();
+
+      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name)) {
+        Type t = mutator.GetType();
+        Type[] interfaces = t.GetInterfaces();
+
+        for(int i = 0; i < interfaces.Length; i++) {
+          if (manipulatorType.IsAssignableFrom(interfaces[i])) {
+            bool assignable = false;
+            for (int j = 0; j < interfaces.Length; j++) {
+              if (i != j && interfaces[i].IsAssignableFrom(interfaces[j])) {
+                assignable = true;
+                break;
+              }
+            }
+
+            if(!assignable)
+              manipulatorInterfaces.Add(interfaces[i]);
+          }         
+        }
+      }
+
+      foreach (Type manipulatorInterface in manipulatorInterfaces) {
+        //manipulatorInterface is more specific
+        if (manipulatorType.IsAssignableFrom(manipulatorInterface)) {
+          //and compatible to all other found manipulator types
+          bool compatible = true;
+          foreach (Type manipulatorInterface2 in manipulatorInterfaces) {
+            if (!manipulatorInterface.IsAssignableFrom(manipulatorInterface2)) {
+              compatible = false;
+              break;
+            }
+          }
+
+          if (compatible)
+            manipulatorType = manipulatorInterface;
+        }
+      }
+      
+      Type genericType = typeof(ShakingOperator<>).MakeGenericType(manipulatorType);
+      ShakingParameter.Value = (IShakingOperator)Activator.CreateInstance(genericType, new object[]{});
+
+      ShakingParameter.Value.OnProblemChanged(Problem);
+    }
+    private void UpdateLocalImprovementOperator() {
+      LocalImprovementParameter.Value.OnProblemChanged(Problem);
+    }
+    private void UpdateAnalyzers() {
+      Analyzer.Operators.Clear();
+      if (Problem != null) {
+        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
+          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 1;
+          Analyzer.Operators.Add(analyzer);
+        }
+      }
+      Analyzer.Operators.Add(qualityAnalyzer);
+    }
+    private VariableNeighborhoodSearchMainLoop FindMainLoop(IOperator start) {
+      IOperator mainLoop = start;
+      while (mainLoop != null && !(mainLoop is VariableNeighborhoodSearchMainLoop))
+        mainLoop = ((SingleSuccessorOperator)mainLoop).Successor;
+      if (mainLoop == null) return null;
+      else return (VariableNeighborhoodSearchMainLoop)mainLoop;
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 5753)
@@ -0,0 +1,288 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Selection;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  /// <summary>
+  /// An operator which represents a variable neighborhood search.
+  /// </summary>
+  [Item("VariableNeighborhoodSearchMainLoop", "An operator which represents the main loop of a variable neighborhood search.")]
+  [StorableClass]
+  public sealed class VariableNeighborhoodSearchMainLoop : AlgorithmOperator {
+    #region Parameter properties
+    public ValueLookupParameter<IRandom> RandomParameter {
+      get { return (ValueLookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public LookupParameter<DoubleValue> QualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ValueLookupParameter<IOperator> EvaluatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Evaluator"]; }
+    }
+    public ValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    public ValueLookupParameter<IOperator> AnalyzerParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Analyzer"]; }
+    }
+    public LookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ValueLookupParameter<ILocalImprovementOperator> LocalImprovementParameter {
+      get { return (ValueLookupParameter<ILocalImprovementOperator>)Parameters["LocalImprovement"]; }
+    }
+    public ValueLookupParameter<IShakingOperator> ShakingParameter {
+      get { return (ValueLookupParameter<IShakingOperator>)Parameters["Shaking"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private VariableNeighborhoodSearchMainLoop(bool deserializing) : base(deserializing) { }
+    public VariableNeighborhoodSearchMainLoop()
+      : base() {
+        Initialize();
+    }
+    private VariableNeighborhoodSearchMainLoop(VariableNeighborhoodSearchMainLoop original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableNeighborhoodSearchMainLoop(this, cloner);
+    }
+
+    private void Initialize() {
+      #region Create parameters
+      Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("Evaluator", "The operator used to evaluate solutions. This operator is executed in parallel, if an engine is used which supports parallelization."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
+
+      Parameters.Add(new ValueLookupParameter<IOperator>("Analyzer", "The operator used to analyze the solution."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solutions."));
+      Parameters.Add(new ValueLookupParameter<ILocalImprovementOperator>("LocalImprovement", "The local improvement operation."));
+      Parameters.Add(new ValueLookupParameter<IShakingOperator>("Shaking", "The shaking operation."));
+      #endregion
+
+      #region Create operators
+      VariableCreator variableCreator = new VariableCreator();
+      SubScopesProcessor subScopesProcessor0 = new SubScopesProcessor();
+      Assigner bestQualityInitializer = new Assigner();
+      Placeholder analyzer1 = new Placeholder();
+      ResultsCollector resultsCollector1 = new ResultsCollector();
+
+      CombinedOperator iteration = new CombinedOperator();
+      Assigner iterationInit = new Assigner();
+
+      SubScopesCloner createChild = new SubScopesCloner();
+      SubScopesProcessor childProcessor = new SubScopesProcessor();
+
+      Assigner qualityAssigner = new Assigner();
+      Placeholder shaking = new Placeholder();
+      Placeholder localImprovement = new Placeholder();
+      Placeholder evaluator = new Placeholder();
+      IntCounter evalCounter = new IntCounter();
+
+      QualityComparator qualityComparator = new QualityComparator();
+      ConditionalBranch improvesQualityBranch1 = new ConditionalBranch();
+      ConditionalBranch improvesQualityBranch2 = new ConditionalBranch();
+
+      Assigner bestQualityUpdater = new Assigner();
+
+      BestSelector bestSelector = new BestSelector();
+      RightReducer rightReducer = new RightReducer();
+
+      IntCounter indexCounter = new IntCounter();
+      Assigner indexResetter = new Assigner();
+
+      Placeholder analyzer2 = new Placeholder();
+
+      ConditionalBranch indexTermination = new ConditionalBranch();
+
+      IntCounter iterationsCounter = new IntCounter();
+      Comparator iterationsComparator = new Comparator();
+      ConditionalBranch iterationsTermination = new ConditionalBranch();
+
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Index", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<BoolValue>("Continue", new BoolValue(false)));
+      variableCreator.CollectedValues.Add(new ValueParameter<BoolValue>("IsBetter", new BoolValue(false)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(0)));
+
+      bestQualityInitializer.Name = "Initialize BestQuality";
+      bestQualityInitializer.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityInitializer.RightSideParameter.ActualName = QualityParameter.Name;
+
+      analyzer1.Name = "Analyzer (placeholder)";
+      analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+      resultsCollector1.CopyValue = new BoolValue(false);
+      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Quality", null, "BestQuality"));
+      resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      iteration.Name = "Iteration";
+
+      iterationInit.Name = "Init iteration";
+      iterationInit.LeftSideParameter.ActualName = "Index";
+      iterationInit.RightSideParameter.Value = new IntValue(0);
+
+      createChild.Name = "Clone solution";
+
+      qualityAssigner.Name = "Assign quality";
+      qualityAssigner.LeftSideParameter.ActualName = "OriginalQuality";
+      qualityAssigner.RightSideParameter.ActualName = QualityParameter.Name;
+
+      shaking.Name = "Shaking operator (placeholder)";
+      shaking.OperatorParameter.ActualName = ShakingParameter.Name;
+
+      localImprovement.Name = "Local improvement operator (placeholder)";
+      localImprovement.OperatorParameter.ActualName = LocalImprovementParameter.Name;
+
+      evaluator.Name = "Evaluation operator (placeholder)";
+      evaluator.OperatorParameter.ActualName = EvaluatorParameter.Name;
+
+      evalCounter.Name = "Count evaluations";
+      evalCounter.Increment.Value = 1;
+      evalCounter.ValueParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
+
+      qualityComparator.LeftSideParameter.ActualName = QualityParameter.Name;
+      qualityComparator.RightSideParameter.ActualName = "OriginalQuality";
+      qualityComparator.ResultParameter.ActualName = "IsBetter";
+
+      improvesQualityBranch1.ConditionParameter.ActualName = "IsBetter";
+      improvesQualityBranch2.ConditionParameter.ActualName = "IsBetter";
+
+      bestQualityUpdater.Name = "Update BestQuality";
+      bestQualityUpdater.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityUpdater.RightSideParameter.ActualName = QualityParameter.Name;
+
+      bestSelector.CopySelected = new BoolValue(false);
+      bestSelector.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      bestSelector.NumberOfSelectedSubScopesParameter.Value = new IntValue(1);
+      bestSelector.QualityParameter.ActualName = QualityParameter.Name;
+
+      indexCounter.Name = "Count index";
+      indexCounter.Increment.Value = 1;
+      indexCounter.ValueParameter.ActualName = "Index";
+
+      indexResetter.Name = "Reset index";
+      indexResetter.LeftSideParameter.ActualName = "Index";
+      indexResetter.RightSideParameter.Value = new IntValue(0);
+
+      analyzer2.Name = "Analyzer (placeholder)";
+      analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+      iterationsCounter.Name = "Iterations Counter";
+      iterationsCounter.Increment = new IntValue(1);
+      iterationsCounter.ValueParameter.ActualName = "Iterations";
+
+      iterationsComparator.Name = "Iterations >= MaximumIterations";
+      iterationsComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
+      iterationsComparator.LeftSideParameter.ActualName = "Iterations";
+      iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
+      iterationsComparator.ResultParameter.ActualName = "Terminate";
+
+      iterationsTermination.Name = "Iterations Termination Condition";
+      iterationsTermination.ConditionParameter.ActualName = "Terminate";
+
+      indexTermination.Name = "Index Termination Condition";
+      indexTermination.ConditionParameter.ActualName = "Continue";
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = variableCreator;
+      variableCreator.Successor = subScopesProcessor0;
+      subScopesProcessor0.Operators.Add(bestQualityInitializer);
+      subScopesProcessor0.Successor = analyzer1;
+      analyzer1.Successor = resultsCollector1;
+      /////////
+      resultsCollector1.Successor = iteration;
+
+      iteration.OperatorGraph.InitialOperator = iterationInit;
+      iteration.Successor = iterationsCounter;
+      iterationInit.Successor = createChild;
+
+      createChild.Successor = childProcessor;
+      childProcessor.Operators.Add(new EmptyOperator());
+      childProcessor.Operators.Add(qualityAssigner);
+      childProcessor.Successor = bestSelector;
+      /////////
+      qualityAssigner.Successor = shaking;
+      shaking.Successor = evaluator;
+      evaluator.Successor = evalCounter;
+      evalCounter.Successor = localImprovement;
+      localImprovement.Successor = qualityComparator;
+      qualityComparator.Successor = improvesQualityBranch1;
+      improvesQualityBranch1.TrueBranch = bestQualityUpdater;
+      improvesQualityBranch1.FalseBranch = indexCounter;
+
+      bestQualityUpdater.Successor = indexResetter;
+      indexResetter.Successor = null;
+
+      indexCounter.Successor = null;
+      /////////
+      bestSelector.Successor = rightReducer;
+      rightReducer.Successor = analyzer2;
+      analyzer2.Successor = indexTermination;
+      indexTermination.TrueBranch = improvesQualityBranch2;
+      indexTermination.FalseBranch = null;
+
+      improvesQualityBranch2.TrueBranch = null;
+      improvesQualityBranch2.FalseBranch = createChild;
+
+      iterationsCounter.Successor = iterationsComparator;
+      iterationsComparator.Successor = iterationsTermination;
+      iterationsTermination.TrueBranch = null;
+      iterationsTermination.FalseBranch = iteration;
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      if (LocalImprovementParameter.ActualValue == null || EvaluatorParameter.ActualValue == null)
+        return null;
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj	(revision 5752)
+++ /trunk/sources/HeuristicLab.Operators/3.3/HeuristicLab.Operators-3.3.csproj	(revision 5753)
@@ -124,4 +124,5 @@
       <SubType>Code</SubType>
     </Compile>
+    <Compile Include="SubScopesCloner.cs" />
     <Compile Include="SubScopesCounter.cs" />
     <Compile Include="SubScopesCreator.cs" />
Index: /trunk/sources/HeuristicLab.Operators/3.3/SubScopesCloner.cs
===================================================================
--- /trunk/sources/HeuristicLab.Operators/3.3/SubScopesCloner.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Operators/3.3/SubScopesCloner.cs	(revision 5753)
@@ -0,0 +1,82 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Operators {
+  /// <summary>
+  /// An operator which creates multiple copies of the subscopes of the current scope.
+  /// </summary>
+  [Item("SubScopesCloner", "An operator which creates multiple copies of the subscopes of the current scope.")]
+  [StorableClass]
+  public class SubScopesCloner : SingleSuccessorOperator {
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    private ValueParameter<IntValue> NumberOfCopiesParameter {
+      get { return (ValueParameter<IntValue>)Parameters["NumberOfCopies"]; }
+    }
+
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    public IntValue NumberOfCopies {
+      get { return NumberOfCopiesParameter.Value; }
+      set { NumberOfCopiesParameter.Value = value;  }
+    }
+
+
+    [StorableConstructor]
+    private SubScopesCloner(bool deserializing) : base(deserializing) { }
+    private SubScopesCloner(SubScopesCloner original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public SubScopesCloner()
+      : base() { 
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes should be cloned."));
+      Parameters.Add(new ValueParameter<IntValue>("NumberOfCopies", "The number of copies that should be created.", new IntValue(1)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SubScopesCloner(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ScopeList subScopes = new ScopeList(CurrentScope.SubScopes);
+
+      for (int i = 0; i < NumberOfCopies.Value; i++) {
+        foreach (Scope scope in subScopes) {
+          CurrentScope.SubScopes.Add(scope.Clone() as IScope);
+        }
+      }
+
+       return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 5752)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 5753)
@@ -116,4 +116,5 @@
     <Compile Include="Interfaces\IDiscreteDoubleMatrixModifier.cs" />
     <Compile Include="Interfaces\IGlobalParticleUpdater.cs" />
+    <Compile Include="Interfaces\ILocalImprovementOperator.cs" />
     <Compile Include="Interfaces\ILocalParticleUpdater.cs" />
     <Compile Include="Interfaces\IMultiAnalyzer.cs" />
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 5753)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 5753)
@@ -0,0 +1,33 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Optimization {
+  public interface ILocalImprovementOperator: IOperator {
+    void OnProblemChanged(IProblem problem);
+  }
+}
Index: /trunk/sources/HeuristicLab/3.3/Files.txt
===================================================================
--- /trunk/sources/HeuristicLab/3.3/Files.txt	(revision 5752)
+++ /trunk/sources/HeuristicLab/3.3/Files.txt	(revision 5753)
@@ -14,4 +14,5 @@
 HeuristicLab.Algorithms.SimulatedAnnealing\3.3:HeuristicLab.Algorithms.SimulatedAnnealing-3.3.dll
 HeuristicLab.Algorithms.TabuSearch\3.3:HeuristicLab.Algorithms.TabuSearch-3.3.dll
+HeuristicLab.Algorithms.VariableNeighborhoodSearch\3.3:HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.dll
 HeuristicLab.Analysis\3.3:HeuristicLab.Analysis-3.3.dll
 HeuristicLab.Analysis.Views\3.3:HeuristicLab.Analysis.Views-3.3.dll
