Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearch.cs	(revision 6042)
@@ -185,5 +185,5 @@
       mainLoop.EvaluatedMovesParameter.ActualName = "EvaluatedMoves";
       mainLoop.IterationsParameter.ActualName = "Iterations";
-      mainLoop.BestQualityParameter.ActualName = "BestQuality";
+      mainLoop.BestLocalQualityParameter.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 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs	(revision 6042)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Analysis;
@@ -29,5 +28,4 @@
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
-using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -39,33 +37,65 @@
   [Item("LocalSearchImprovementOperator", "A local search improvement operator.")]
   [StorableClass]
-  public class LocalSearchImprovementOperator : SingleSuccessorOperator, ILocalImprovementOperator {
+  public sealed class LocalSearchImprovementOperator : SingleSuccessorOperator, IGenericLocalImprovementOperator, IStochasticOperator {
+    #region IGenericLocalImprovementOperator Properties
+    public Type ProblemType { get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); } }
+    public IProblem Problem {
+      get { return problem; }
+      set {
+        if (problem != value) {
+          if (value != null && !(value is ISingleObjectiveHeuristicOptimizationProblem))
+            throw new ArgumentException("Only problems of type " + ProblemType.ToString() + " can be assigned.");
+          if (problem != null) DeregisterProblemEventHandlers();
+          problem = (ISingleObjectiveHeuristicOptimizationProblem)value;
+          if (problem != null) RegisterProblemEventHandlers();
+          UpdateProblem();
+        }
+      }
+    }
+    #endregion
+
+    [Storable]
+    private ISingleObjectiveHeuristicOptimizationProblem problem;
     [Storable]
     private LocalSearchMainLoop loop;
-
     [Storable]
     private BestAverageWorstQualityAnalyzer qualityAnalyzer;
 
-    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
+    #region Parameter Properties
+    public ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
       get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
     }
-    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
+    public ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
       get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
     }
-    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
+    public 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 IValueLookupParameter<IntValue> SampleSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["SampleSize"]; }
     }
     public ValueParameter<MultiAnalyzer> AnalyzerParameter {
       get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
     }
-
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    #region ILocalImprovementOperator Parameters
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    #endregion
+    #endregion
+
+    #region Properties
     public IMoveGenerator MoveGenerator {
       get { return MoveGeneratorParameter.Value; }
@@ -84,58 +114,114 @@
       set { AnalyzerParameter.Value = value; }
     }
+    #endregion
 
     [StorableConstructor]
-    protected LocalSearchImprovementOperator(bool deserializing) : base(deserializing) { }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      Initialize();
-    }
-    protected LocalSearchImprovementOperator(LocalSearchImprovementOperator original, Cloner cloner)
+    private LocalSearchImprovementOperator(bool deserializing) : base(deserializing) { }
+    private 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);
+      this.problem = cloner.Clone(original.problem);
+      RegisterEventHandlers();
     }
     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 ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
+      Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(300)));
       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() {
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The name of the collection where the results are stored."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality/fitness value of a solution."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+
+      loop = new LocalSearchMainLoop();
+      ParameterizeLSMainLoop();
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      Analyzer.Operators.Add(qualityAnalyzer);
+
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LocalSearchImprovementOperator(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    #region Event Handler Registration
+    private void RegisterEventHandlers() {
       MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
-    }
-
-    public void OnProblemChanged(IProblem problem) {
-      UpdateMoveOperators(problem);
+      if (problem != null)
+        RegisterProblemEventHandlers();
+    }
+
+    private void RegisterProblemEventHandlers() {
+      problem.Reset += new EventHandler(problem_Reset);
+      problem.OperatorsChanged += new EventHandler(problem_OperatorsChanged);
+    }
+
+    private void DeregisterProblemEventHandlers() {
+      problem.Reset -= new EventHandler(problem_Reset);
+      problem.OperatorsChanged -= new EventHandler(problem_OperatorsChanged);
+    }
+    #endregion
+
+    #region Event Handlers
+    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
       ChooseMoveOperators();
-
-      ParameterizeMoveGenerators(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      ParameterizeMoveEvaluators(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      ParameterizeMoveMakers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-
-      ParameterizeAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      UpdateAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-    }
-
-    void ParameterizeAnalyzers(ISingleObjectiveHeuristicOptimizationProblem problem) {
-      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      ParameterizeLSMainLoop();
+    }
+
+    private void problem_Reset(object sender, EventArgs e) {
+      UpdateProblem();
+    }
+
+    private void problem_OperatorsChanged(object sender, EventArgs e) {
+      UpdateProblem();
+    }
+    #endregion
+
+    #region Parameterize and Update Methods
+    private void UpdateProblem() {
+      UpdateMoveOperators();
+      ChooseMoveOperators();
+
+      ParameterizeMoveGenerators();
+
+      ParameterizeLSMainLoop();
+      ParameterizeAnalyzers();
+    }
+
+    private void ParameterizeLSMainLoop() {
+      loop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+      loop.BestLocalQualityParameter.ActualName = QualityParameter.Name;
+      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.Name;
+      loop.IterationsParameter.ActualName = "LocalIterations";
+      loop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      loop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
+      loop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
+      loop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
+      loop.QualityParameter.ActualName = QualityParameter.Name;
+      loop.RandomParameter.ActualName = RandomParameter.Name;
+      loop.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      if (problem != null) {
+        loop.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
+        loop.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
+      }
+      if (MoveEvaluator != null) {
+        loop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
+    }
+
+    private void ParameterizeAnalyzers() {
+      qualityAnalyzer.ResultsParameter.ActualName = ResultsParameter.Name;
       if (problem != null) {
         qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
@@ -146,22 +232,5 @@
     }
 
-    void UpdateAnalyzers(ISingleObjectiveHeuristicOptimizationProblem 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) {
+    private void UpdateMoveOperators() {
       IMoveGenerator oldMoveGenerator = MoveGenerator;
       IMoveMaker oldMoveMaker = MoveMaker;
@@ -171,65 +240,38 @@
 
       if (problem != null) {
-        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>().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);
-        }
+        foreach (IExhaustiveMoveGenerator generator in problem.Operators.OfType<IExhaustiveMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+
+        if (oldMoveGenerator != null) {
+          IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+          if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+        }
+
+        ChooseMoveOperators(oldMoveMaker, oldMoveEvaluator);
+      }
+    }
+
+    private void ChooseMoveOperators(IMoveMaker oldMoveMaker = null, ISingleObjectiveMoveEvaluator oldMoveEvaluator = null) {
+      if (oldMoveMaker == null) oldMoveMaker = MoveMaker;
+      if (oldMoveEvaluator == null) oldMoveEvaluator = MoveEvaluator;
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
+
+      if (MoveGenerator != null && Problem != null) {
+        IMoveGenerator generator = MoveGeneratorParameter.Value;
+        foreach (IMoveMaker moveMaker in MoveHelper.GetCompatibleMoveMakers(generator, Problem.Operators).OrderBy(x => x.Name))
+          MoveMakerParameter.ValidValues.Add(moveMaker);
+        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in MoveHelper.GetCompatibleSingleObjectiveMoveEvaluators(generator, Problem.Operators).OrderBy(x => x.Name))
+          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
+
         if (oldMoveMaker != null) {
-          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+          IMoveMaker mm = MoveMakerParameter.ValidValues.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());
+          ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
           if (me != null) MoveEvaluator = me;
-          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
         }
       }
@@ -242,5 +284,5 @@
     }
 
-    private void ParameterizeMoveGenerators(ISingleObjectiveHeuristicOptimizationProblem problem) {
+    private void ParameterizeMoveGenerators() {
       if (problem != null) {
         foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
@@ -248,28 +290,18 @@
       }
     }
-    private void ParameterizeMoveEvaluators(ISingleObjectiveHeuristicOptimizationProblem problem) {
-      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
-      }
-    }
-    private void ParameterizeMoveMakers(ISingleObjectiveHeuristicOptimizationProblem 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;
-      }
-    }
+    #endregion
 
     public override IOperation Apply() {
-      Scope subScope = new Scope();
+      IScope currentScope = ExecutionContext.Scope;
+
+      Scope localScope = 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);
+      foreach (IVariable var in currentScope.Variables)
+        individual.Variables.Add(var); // add reference to variable otherwise the analyzer fails (it's looking down the tree)
+
+      localScope.SubScopes.Add(individual);
+      currentScope.SubScopes.Add(localScope);
+      int index = currentScope.SubScopes.Count - 1;
 
       SubScopesProcessor processor = new SubScopesProcessor();
@@ -279,25 +311,24 @@
       remover.SubScopeIndexParameter.Value = new IntValue(index);
 
-      for (int i = 0; i < index; i++) {
-        processor.Operators.Add(new EmptyOperator());
+      if (index > 0) {
+        EmptyOperator eo = new EmptyOperator();
+        for (int i = 0; i < index - 1; i++) {
+          processor.Operators.Add(eo);
+        }
       }
 
       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.CollectedValues.Add(new ValueParameter<IntValue>(loop.IterationsParameter.ActualName, new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>(loop.BestLocalQualityParameter.ActualName, 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);
+      OperationCollection next = new OperationCollection(base.Apply());
+      next.Insert(0, ExecutionContext.CreateChildOperation(processor));
+
+      return next;
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchMainLoop.cs	(revision 6042)
@@ -46,5 +46,5 @@
       get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
-    public LookupParameter<DoubleValue> BestQualityParameter {
+    public LookupParameter<DoubleValue> BestLocalQualityParameter {
       get { return (LookupParameter<DoubleValue>)Parameters["BestLocalQuality"]; }
     }
@@ -56,5 +56,5 @@
     }
     public LookupParameter<IntValue> IterationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["LocalIterations"]; }
+      get { return (LookupParameter<IntValue>)Parameters["Iterations"]; }
     }
     public ValueLookupParameter<IntValue> MaximumIterationsParameter {
@@ -85,5 +85,5 @@
     public LocalSearchMainLoop()
       : base() {
-        Initialize();
+      Initialize();
     }
     private LocalSearchMainLoop(LocalSearchMainLoop original, Cloner cloner)
@@ -100,7 +100,7 @@
       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 ValueLookupParameter<DoubleValue>("BestKnownQuality", "The problem's 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 LookupParameter<IntValue>("Iterations", "The number of iterations performed."));
       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."));
@@ -140,5 +140,5 @@
 
       bestQualityInitializer.Name = "Initialize BestQuality";
-      bestQualityInitializer.LeftSideParameter.ActualName = BestQualityParameter.Name;
+      bestQualityInitializer.LeftSideParameter.ActualName = BestLocalQualityParameter.Name;
       bestQualityInitializer.RightSideParameter.ActualName = QualityParameter.Name;
 
@@ -148,5 +148,5 @@
       resultsCollector1.CopyValue = new BoolValue(false);
       resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>(IterationsParameter.Name));
-      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>(BestQualityParameter.Name, null, BestQualityParameter.Name));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>(BestLocalQualityParameter.Name, null, BestLocalQualityParameter.Name));
       resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
 
@@ -177,9 +177,9 @@
 
       bestQualityUpdater.Name = "Update BestQuality";
-      bestQualityUpdater.LeftSideParameter.ActualName = BestQualityParameter.Name;
+      bestQualityUpdater.LeftSideParameter.ActualName = BestLocalQualityParameter.Name;
       bestQualityUpdater.RightSideParameter.ActualName = QualityParameter.Name;
 
       resultsCollector2.CopyValue = new BoolValue(false);
-      resultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>(BestQualityParameter.Name, null, BestQualityParameter.Name));
+      resultsCollector2.CollectedValues.Add(new LookupParameter<DoubleValue>(BestLocalQualityParameter.Name, null, BestLocalQualityParameter.Name));
       resultsCollector2.ResultsParameter.ActualName = ResultsParameter.Name;
 
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingImprovementOperator.cs	(revision 6042)
@@ -21,17 +21,13 @@
 
 using System;
-using System.Collections.Generic;
 using System.Linq;
-using System.Text;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
 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;
 
@@ -42,11 +38,33 @@
   [Item("SimulatedAnnealingImprovementOperator", "A simulated annealing improvement operator.")]
   [StorableClass]
-  public class SimulatedAnnealingImprovementOperator: SingleSuccessorOperator, ILocalImprovementOperator {
+  public sealed class SimulatedAnnealingImprovementOperator : SingleSuccessorOperator, IGenericLocalImprovementOperator, IStochasticOperator {
+    #region IGenericLocalImprovementOperator Properties
+    public Type ProblemType { get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); } }
+    public IProblem Problem {
+      get { return problem; }
+      set {
+        if (problem != value) {
+          if (value != null && !(value is ISingleObjectiveHeuristicOptimizationProblem))
+            throw new ArgumentException("Only problems of type " + ProblemType.ToString() + " can be assigned.");
+          if (problem != null) DeregisterProblemEventHandlers();
+          problem = (ISingleObjectiveHeuristicOptimizationProblem)value;
+          if (problem != null) RegisterProblemEventHandlers();
+          UpdateProblem();
+        }
+      }
+    }
+    #endregion
+
+    [Storable]
+    private ISingleObjectiveHeuristicOptimizationProblem problem;
     [Storable]
     private SimulatedAnnealingMainLoop loop;
-
     [Storable]
     private BestAverageWorstQualityAnalyzer qualityAnalyzer;
-    
+
+    #region Parameter Properties
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
     private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
       get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
@@ -58,12 +76,6 @@
       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"]; }
+    private IValueLookupParameter<IntValue> InnerIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["InnerIterations"]; }
     }
     public ValueParameter<MultiAnalyzer> AnalyzerParameter {
@@ -79,5 +91,21 @@
       get { return (ConstrainedValueParameter<IDiscreteDoubleValueModifier>)Parameters["AnnealingOperator"]; }
     }
-
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    #region ILocalImprovementOperator Parameters
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    #endregion
+    #endregion
+
+    #region Properties
     public IMoveGenerator MoveGenerator {
       get { return MoveGeneratorParameter.Value; }
@@ -96,48 +124,85 @@
       set { AnalyzerParameter.Value = value; }
     }
+    #endregion
 
     [StorableConstructor]
-    protected SimulatedAnnealingImprovementOperator(bool deserializing) : base(deserializing) {}
+    private SimulatedAnnealingImprovementOperator(bool deserializing) : base(deserializing) { }
+    private SimulatedAnnealingImprovementOperator(SimulatedAnnealingImprovementOperator original, Cloner cloner)
+      : base(original, cloner) {
+      this.problem = cloner.Clone(original.problem);
+      this.loop = cloner.Clone(original.loop);
+      this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+      RegisterEventHandlers();
+    }
+    public SimulatedAnnealingImprovementOperator()
+      : base() {
+      loop = new SimulatedAnnealingMainLoop();
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      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 ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
+      Parameters.Add(new ValueLookupParameter<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."));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", "The variable where the results are stored."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The quality/fitness value of a solution."));
+
+      foreach (IDiscreteDoubleValueModifier op in ApplicationManager.Manager.GetInstances<IDiscreteDoubleValueModifier>().OrderBy(x => x.Name))
+        AnnealingOperatorParameter.ValidValues.Add(op);
+
+      ParameterizeAnnealingOperators();
+      ParameterizeSAMainLoop();
+
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimulatedAnnealingImprovementOperator(this, cloner);
+    }
+
     [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() {
+      RegisterEventHandlers();
+    }
+
+    #region Event Handler Registration
+    private void RegisterEventHandlers() {
       MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
-    }
+      if (problem != null)
+        RegisterProblemEventHandlers();
+    }
+
+    private void RegisterProblemEventHandlers() {
+      problem.Reset += new EventHandler(problem_Reset);
+      problem.OperatorsChanged += new EventHandler(problem_OperatorsChanged);
+    }
+
+    private void DeregisterProblemEventHandlers() {
+      problem.Reset -= new EventHandler(problem_Reset);
+      problem.OperatorsChanged -= new EventHandler(problem_OperatorsChanged);
+    }
+    #endregion
+
+    #region Event Handlers
+    private void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
+      ChooseMoveOperators();
+      ParameterizeSAMainLoop();
+    }
+
+    private void problem_Reset(object sender, EventArgs e) {
+      UpdateProblem();
+    }
+
+    private void problem_OperatorsChanged(object sender, EventArgs e) {
+      UpdateProblem();
+    }
+    #endregion
 
     private void ParameterizeAnnealingOperators() {
@@ -152,17 +217,16 @@
     }
 
-    public void OnProblemChanged(IProblem problem) {
-      UpdateMoveOperators(problem);
+    public void UpdateProblem() {
+      UpdateMoveOperators();
       ChooseMoveOperators();
 
-      ParameterizeMoveGenerators(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      ParameterizeMoveEvaluators(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      ParameterizeMoveMakers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-
-      ParameterizeAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-      UpdateAnalyzers(problem as ISingleObjectiveHeuristicOptimizationProblem);
-    }
-
-    void ParameterizeAnalyzers(ISingleObjectiveHeuristicOptimizationProblem problem) {
+      ParameterizeMoveGenerators();
+
+      ParameterizeSAMainLoop();
+      ParameterizeAnalyzers();
+      UpdateAnalyzers();
+    }
+
+    private void ParameterizeAnalyzers() {
       qualityAnalyzer.ResultsParameter.ActualName = "Results";
       if (problem != null) {
@@ -174,5 +238,26 @@
     }
 
-    void UpdateAnalyzers(ISingleObjectiveHeuristicOptimizationProblem problem) {
+    private void ParameterizeSAMainLoop() {
+      loop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+      loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.Name;
+      loop.IterationsParameter.ActualName = "LocalIterations";
+      loop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      loop.MoveEvaluatorParameter.ActualName = MoveEvaluatorParameter.Name;
+      loop.MoveGeneratorParameter.ActualName = MoveGeneratorParameter.Name;
+      loop.MoveMakerParameter.ActualName = MoveMakerParameter.Name;
+      loop.QualityParameter.ActualName = QualityParameter.Name;
+      loop.RandomParameter.ActualName = RandomParameter.Name;
+      loop.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      if (problem != null) {
+        loop.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
+        loop.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
+      }
+      if (MoveEvaluator != null) {
+        loop.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
+    }
+
+    private void UpdateAnalyzers() {
       Analyzer.Operators.Clear();
       if (problem != null) {
@@ -187,9 +272,5 @@
     }
 
-    void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
-      ChooseMoveOperators();
-    }
-
-    private void UpdateMoveOperators(IProblem problem) {
+    private void UpdateMoveOperators() {
       IMoveGenerator oldMoveGenerator = MoveGenerator;
       IMoveMaker oldMoveMaker = MoveMaker;
@@ -199,66 +280,39 @@
 
       if (problem != null) {
-        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>().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;
+        foreach (IExhaustiveMoveGenerator generator in problem.Operators.OfType<IExhaustiveMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+
+        if (oldMoveGenerator != null) {
+          IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+          if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+        }
+
+        ChooseMoveOperators(oldMoveMaker, oldMoveEvaluator);
+      }
+    }
+
+    private void ChooseMoveOperators(IMoveMaker oldMoveMaker = null, ISingleObjectiveMoveEvaluator oldMoveEvaluator = null) {
+      if (oldMoveMaker == null) oldMoveMaker = MoveMaker;
+      if (oldMoveEvaluator == null) oldMoveEvaluator = MoveEvaluator;
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
 
       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);
-        }
+        IMoveGenerator generator = MoveGeneratorParameter.Value;
+        foreach (IMoveMaker moveMaker in MoveHelper.GetCompatibleMoveMakers(generator, Problem.Operators).OrderBy(x => x.Name))
+          MoveMakerParameter.ValidValues.Add(moveMaker);
+        foreach (ISingleObjectiveMoveEvaluator moveEvaluator in MoveHelper.GetCompatibleSingleObjectiveMoveEvaluators(generator, Problem.Operators).OrderBy(x => x.Name))
+          MoveEvaluatorParameter.ValidValues.Add(moveEvaluator);
+
         if (oldMoveMaker != null) {
-          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+          IMoveMaker mm = MoveMakerParameter.ValidValues.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());
+          ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
           if (me != null) MoveEvaluator = me;
-          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
-        } 
+        }
       }
     }
@@ -270,5 +324,5 @@
     }
 
-    private void ParameterizeMoveGenerators(ISingleObjectiveHeuristicOptimizationProblem problem) {
+    private void ParameterizeMoveGenerators() {
       if (problem != null) {
         foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
@@ -276,28 +330,17 @@
       }
     }
-    private void ParameterizeMoveEvaluators(ISingleObjectiveHeuristicOptimizationProblem problem) {
-      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
-        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
-      }
-    }
-    private void ParameterizeMoveMakers(ISingleObjectiveHeuristicOptimizationProblem 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();
+      IScope currentScope = ExecutionContext.Scope;
+
+      Scope localScope = 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);
+      foreach (IVariable var in currentScope.Variables)
+        individual.Variables.Add(var); // add reference to variable otherwise the analyzer fails (it's looking down the tree)
+
+      localScope.SubScopes.Add(individual);
+      currentScope.SubScopes.Add(localScope);
+      int index = currentScope.SubScopes.Count - 1;
 
       SubScopesProcessor processor = new SubScopesProcessor();
@@ -307,24 +350,23 @@
       remover.SubScopeIndexParameter.Value = new IntValue(index);
 
-      for (int i = 0; i < index; i++) {
-        processor.Operators.Add(new EmptyOperator());
+      if (index > 0) {
+        EmptyOperator eo = new EmptyOperator();
+        for (int i = 0; i < index - 1; i++) {
+          processor.Operators.Add(eo);
+        }
       }
 
       VariableCreator variableCreator = new VariableCreator();
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("LocalIterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>(loop.IterationsParameter.ActualName, 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);
+      OperationCollection next = new OperationCollection(base.Apply());
+      next.Insert(0, ExecutionContext.CreateChildOperation(processor));
+
+      return next;
     }
   }
Index: /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.SimulatedAnnealing/3.3/SimulatedAnnealingMainLoop.cs	(revision 6042)
@@ -61,5 +61,5 @@
     }
     public LookupParameter<IntValue> IterationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["LocalIterations"]; }
+      get { return (LookupParameter<IntValue>)Parameters["Iterations"]; }
     }
     public ValueLookupParameter<IntValue> MaximumIterationsParameter {
@@ -112,5 +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 LookupParameter<IntValue>("Iterations", "The number of iterations."));
       Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of iterations which should be processed."));
 
@@ -231,4 +231,13 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code (remove with 3.4)
+      if (!Parameters.ContainsKey("Iterations"))
+        Parameters.Add(new LookupParameter<IntValue>("Iterations", "The number of iterations."));
+      #endregion
+    }
+
     public override IOperation Apply() {
       if (MoveGeneratorParameter.ActualValue == null || MoveEvaluatorParameter.ActualValue == null || MoveMakerParameter.ActualValue == null)
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 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj	(revision 6042)
@@ -108,7 +108,5 @@
   <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" />
@@ -120,8 +118,4 @@
   </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>
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs.frame	(revision 6042)
@@ -28,5 +28,4 @@
   [Plugin("HeuristicLab.Algorithms.VariableNeighborhoodSearch", "3.3.3.$WCREV$")]
   [PluginFile("HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.Algorithms.LocalSearch", "3.3")]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]  
   [PluginDependency("HeuristicLab.Collections", "3.3")]
Index: unk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs	(revision 6041)
+++ 	(revision )
@@ -1,33 +1,0 @@
-﻿#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: unk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 6041)
+++ 	(revision )
@@ -1,93 +1,0 @@
-﻿#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 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs	(revision 6042)
@@ -1,6 +1,25 @@
-﻿using System;
-using System.Collections.Generic;
+﻿#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.Linq;
-using HeuristicLab.Algorithms.LocalSearch;
 using HeuristicLab.Analysis;
 using HeuristicLab.Common;
@@ -12,4 +31,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Random;
 
@@ -32,24 +52,24 @@
 
     #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 FixedValueParameter<IntValue> SeedParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    private FixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (FixedValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
+    }
+    private ConstrainedValueParameter<ILocalImprovementOperator> LocalImprovementParameter {
+      get { return (ConstrainedValueParameter<ILocalImprovementOperator>)Parameters["LocalImprovement"]; }
+    }
+    private ConstrainedValueParameter<IMultiNeighborhoodShakingOperator> ShakingOperatorParameter {
+      get { return (ConstrainedValueParameter<IMultiNeighborhoodShakingOperator>)Parameters["ShakingOperator"]; }
+    }
+    private FixedValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["MaximumIterations"]; }
     }
     private ValueParameter<MultiAnalyzer> AnalyzerParameter {
       get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
     }
-    private VariableNeighborhoodSearchMainLoop VNSMainLoop {
-      get { return FindMainLoop(SolutionsCreator.Successor); }
+    public FixedValueParameter<IntValue> LocalImprovementMaximumIterationsParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["LocalImprovementMaximumIterations"]; }
     }
     #endregion
@@ -66,4 +86,7 @@
       get { return (SolutionsCreator)RandomCreator.Successor; }
     }
+    private VariableNeighborhoodSearchMainLoop MainLoop {
+      get { return FindMainLoop(SolutionsCreator.Successor); }
+    }
     #endregion
 
@@ -73,23 +96,17 @@
     [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);
+      RegisterEventHandlers();
     }
     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 FixedValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new ConstrainedValueParameter<ILocalImprovementOperator>("LocalImprovement", "The local improvement operation"));
+      Parameters.Add(new ConstrainedValueParameter<IMultiNeighborhoodShakingOperator>("ShakingOperator", "The operator that performs the shaking of solutions."));
+      Parameters.Add(new FixedValueParameter<IntValue>("MaximumIterations", "The maximum number of iterations which should be processed.", new IntValue(50)));
+      Parameters.Add(new FixedValueParameter<IntValue>("LocalImprovementMaximumIterations", "The maximum number of iterations which should be performed in the local improvement phase.", new IntValue(50)));
       Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
 
@@ -112,13 +129,21 @@
 
       variableCreator.Name = "Initialize Evaluated Solutions";
-      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue()));
+
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("CurrentNeighborhoodIndex", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("NeighborhoodCount", new IntValue(0)));
       variableCreator.Successor = resultsCollector;
 
       resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
       resultsCollector.ResultsParameter.ActualName = "Results";
       resultsCollector.Successor = mainLoop;
 
+      mainLoop.IterationsParameter.ActualName = "Iterations";
+      mainLoop.CurrentNeighborhoodIndexParameter.ActualName = "CurrentNeighborhoodIndex";
+      mainLoop.NeighborhoodCountParameter.ActualName = "NeighborhoodCount";
       mainLoop.LocalImprovementParameter.ActualName = LocalImprovementParameter.Name;
-      mainLoop.ShakingParameter.ActualName = ShakingParameter.Name;
+      mainLoop.ShakingOperatorParameter.ActualName = ShakingOperatorParameter.Name;
       mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
       mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
@@ -127,9 +152,19 @@
       mainLoop.EvaluatedSolutionsParameter.ActualName = "EvaluatedSolutions";
 
+      InitializeLocalImprovementOperators();
       qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
       ParameterizeAnalyzers();
       UpdateAnalyzers();
 
-      Initialize();
+      RegisterEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableNeighborhoodSearch(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
     }
 
@@ -138,27 +173,28 @@
     }
 
-    private void Initialize() {
+    private void RegisterEventHandlers() {
+      LocalImprovementParameter.ValueChanged += new EventHandler(LocalImprovementParameter_ValueChanged);
       if (Problem != null) {
         Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       }
-      LocalImprovementParameter.ValueChanged += new EventHandler(LocalImprovementParameter_ValueChanged);
     }
 
     #region Events
     protected override void OnProblemChanged() {
+      InitializeLocalImprovementOperators();
+      UpdateShakingOperators();
+      UpdateAnalyzers();
+
       ParameterizeStochasticOperator(Problem.SolutionCreator);
       ParameterizeStochasticOperator(Problem.Evaluator);
       foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
       ParameterizeSolutionsCreator();
-      ParameterizeVNSMainLoop();
+      ParameterizeMainLoop();
       ParameterizeAnalyzers();
       ParameterizeIterationBasedOperators();
-      UpdateShakingOperator();
-      UpdateLocalImprovementOperator();
-      UpdateAnalyzers();
+      ParameterizeLocalImprovementOperators();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
       base.OnProblemChanged();
     }
-
     protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
       ParameterizeStochasticOperator(Problem.SolutionCreator);
@@ -169,5 +205,5 @@
       ParameterizeStochasticOperator(Problem.Evaluator);
       ParameterizeSolutionsCreator();
-      ParameterizeVNSMainLoop();
+      ParameterizeMainLoop();
       ParameterizeAnalyzers();
       Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
@@ -175,20 +211,16 @@
     }
     protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      UpdateShakingOperators();
+      UpdateAnalyzers();
       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();
+      ParameterizeMainLoop();
       ParameterizeAnalyzers();
     }
-
-    void LocalImprovementParameter_ValueChanged(object sender, EventArgs e) {
-      if (LocalImprovementParameter.Value != null)
-        LocalImprovementParameter.Value.OnProblemChanged(Problem);
+    private void LocalImprovementParameter_ValueChanged(object sender, EventArgs e) {
+      ParameterizeLocalImprovementOperators();
     }
     #endregion
@@ -203,8 +235,8 @@
         ((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 ParameterizeMainLoop() {
+      MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+      MainLoop.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
     }
     private void ParameterizeAnalyzers() {
@@ -221,56 +253,35 @@
         foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
           op.IterationsParameter.ActualName = "Iterations";
-          op.MaximumIterationsParameter.ActualName = "MaximumIterations";
+          op.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
         }
       }
     }
-    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]);
-          }
+    private void ParameterizeLocalImprovementOperators() {
+      foreach (ILocalImprovementOperator op in LocalImprovementParameter.ValidValues) {
+        if (op != LocalImprovementParameter.Value) op.Problem = null;
+        op.MaximumIterationsParameter.Value = null;
+        op.MaximumIterationsParameter.ActualName = LocalImprovementMaximumIterationsParameter.Name;
+      }
+      if (LocalImprovementParameter.Value != null)
+        LocalImprovementParameter.Value.Problem = Problem;
+    }
+    private void InitializeLocalImprovementOperators() {
+      if (Problem == null) {
+        LocalImprovementParameter.ValidValues.Clear();
+      } else {
+        LocalImprovementParameter.ValidValues.RemoveWhere(x => !x.ProblemType.IsAssignableFrom(Problem.GetType()));
+        foreach (ILocalImprovementOperator op in ApplicationManager.Manager.GetInstances<ILocalImprovementOperator>().Where(x => x.ProblemType.IsAssignableFrom(Problem.GetType()))) {
+          if (!LocalImprovementParameter.ValidValues.Any(x => x.GetType() == op.GetType()))
+            LocalImprovementParameter.ValidValues.Add(op);
         }
       }
-
-      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 UpdateShakingOperators() {
+      ShakingOperatorParameter.ValidValues.Clear();
+      foreach (IMultiNeighborhoodShakingOperator op in Problem.Operators.OfType<IMultiNeighborhoodShakingOperator>()) {
+        ShakingOperatorParameter.ValidValues.Add(op);
+        op.CurrentNeighborhoodIndexParameter.ActualName = "CurrentNeighborhoodIndex";
+        op.NeighborhoodCountParameter.ActualName = "NeighborhoodCount";
+      }
     }
     private void UpdateAnalyzers() {
Index: /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 6042)
@@ -20,17 +20,13 @@
 #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.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
 using HeuristicLab.Parameters;
-using HeuristicLab.Data;
-using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Selection;
-using HeuristicLab.Optimization;
 
 namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
@@ -42,36 +38,45 @@
   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"]; }
+    public IValueLookupParameter<IRandom> RandomParameter {
+      get { return (IValueLookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public IValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public IValueLookupParameter<IOperator> EvaluatorParameter {
+      get { return (IValueLookupParameter<IOperator>)Parameters["Evaluator"]; }
+    }
+    public ILookupParameter<IntValue> IterationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Iterations"]; }
+    }
+    public IValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public IValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (IValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    public IValueLookupParameter<IOperator> AnalyzerParameter {
+      get { return (IValueLookupParameter<IOperator>)Parameters["Analyzer"]; }
+    }
+    public ILookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ILookupParameter<IntValue> CurrentNeighborhoodIndexParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["CurrentNeighborhoodIndex"]; }
+    }
+    public ILookupParameter<IntValue> NeighborhoodCountParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["NeighborhoodCount"]; }
+    }
+    public IValueLookupParameter<ILocalImprovementOperator> LocalImprovementParameter {
+      get { return (IValueLookupParameter<ILocalImprovementOperator>)Parameters["LocalImprovement"]; }
+    }
+    public IValueLookupParameter<IMultiNeighborhoodShakingOperator> ShakingOperatorParameter {
+      get { return (IValueLookupParameter<IMultiNeighborhoodShakingOperator>)Parameters["ShakingOperator"]; }
     }
     #endregion
@@ -81,5 +86,5 @@
     public VariableNeighborhoodSearchMainLoop()
       : base() {
-        Initialize();
+      Initialize();
     }
     private VariableNeighborhoodSearchMainLoop(VariableNeighborhoodSearchMainLoop original, Cloner cloner)
@@ -97,11 +102,13 @@
       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 LookupParameter<IntValue>("Iterations", "The iterations to count."));
       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."));
+      Parameters.Add(new ValueLookupParameter<IMultiNeighborhoodShakingOperator>("ShakingOperator", "The shaking operation."));
+      Parameters.Add(new LookupParameter<IntValue>("CurrentNeighborhoodIndex", "The index of the current shaking operation that should be applied."));
+      Parameters.Add(new LookupParameter<IntValue>("NeighborhoodCount", "The number of neighborhood operators used for shaking."));
       #endregion
 
@@ -126,6 +133,5 @@
 
       QualityComparator qualityComparator = new QualityComparator();
-      ConditionalBranch improvesQualityBranch1 = new ConditionalBranch();
-      ConditionalBranch improvesQualityBranch2 = new ConditionalBranch();
+      ConditionalBranch improvesQualityBranch = new ConditionalBranch();
 
       Assigner bestQualityUpdater = new Assigner();
@@ -139,4 +145,5 @@
       Placeholder analyzer2 = new Placeholder();
 
+      Comparator indexComparator = new Comparator();
       ConditionalBranch indexTermination = new ConditionalBranch();
 
@@ -145,7 +152,4 @@
       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)));
@@ -159,12 +163,11 @@
 
       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";
+      iteration.Name = "MainLoop Body";
+
+      iterationInit.Name = "Init k = 0";
+      iterationInit.LeftSideParameter.ActualName = CurrentNeighborhoodIndexParameter.Name;
       iterationInit.RightSideParameter.Value = new IntValue(0);
 
@@ -176,5 +179,5 @@
 
       shaking.Name = "Shaking operator (placeholder)";
-      shaking.OperatorParameter.ActualName = ShakingParameter.Name;
+      shaking.OperatorParameter.ActualName = ShakingOperatorParameter.Name;
 
       localImprovement.Name = "Local improvement operator (placeholder)";
@@ -192,6 +195,5 @@
       qualityComparator.ResultParameter.ActualName = "IsBetter";
 
-      improvesQualityBranch1.ConditionParameter.ActualName = "IsBetter";
-      improvesQualityBranch2.ConditionParameter.ActualName = "IsBetter";
+      improvesQualityBranch.ConditionParameter.ActualName = "IsBetter";
 
       bestQualityUpdater.Name = "Update BestQuality";
@@ -204,10 +206,10 @@
       bestSelector.QualityParameter.ActualName = QualityParameter.Name;
 
-      indexCounter.Name = "Count index";
+      indexCounter.Name = "Count neighborhood index";
       indexCounter.Increment.Value = 1;
-      indexCounter.ValueParameter.ActualName = "Index";
-
-      indexResetter.Name = "Reset index";
-      indexResetter.LeftSideParameter.ActualName = "Index";
+      indexCounter.ValueParameter.ActualName = CurrentNeighborhoodIndexParameter.Name;
+
+      indexResetter.Name = "Reset neighborhood index";
+      indexResetter.LeftSideParameter.ActualName = CurrentNeighborhoodIndexParameter.Name;
       indexResetter.RightSideParameter.Value = new IntValue(0);
 
@@ -217,9 +219,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";
@@ -228,6 +230,12 @@
       iterationsTermination.ConditionParameter.ActualName = "Terminate";
 
+      indexComparator.Name = "k < k_max (index condition)";
+      indexComparator.LeftSideParameter.ActualName = CurrentNeighborhoodIndexParameter.Name;
+      indexComparator.RightSideParameter.ActualName = NeighborhoodCountParameter.Name;
+      indexComparator.Comparison = new Comparison(ComparisonType.Less);
+      indexComparator.ResultParameter.ActualName = "ContinueIteration";
+
       indexTermination.Name = "Index Termination Condition";
-      indexTermination.ConditionParameter.ActualName = "Continue";
+      indexTermination.ConditionParameter.ActualName = "ContinueIteration";
       #endregion
 
@@ -255,7 +263,7 @@
       evalCounter.Successor = localImprovement;
       localImprovement.Successor = qualityComparator;
-      qualityComparator.Successor = improvesQualityBranch1;
-      improvesQualityBranch1.TrueBranch = bestQualityUpdater;
-      improvesQualityBranch1.FalseBranch = indexCounter;
+      qualityComparator.Successor = improvesQualityBranch;
+      improvesQualityBranch.TrueBranch = bestQualityUpdater;
+      improvesQualityBranch.FalseBranch = indexCounter;
 
       bestQualityUpdater.Successor = indexResetter;
@@ -266,10 +274,8 @@
       bestSelector.Successor = rightReducer;
       rightReducer.Successor = analyzer2;
-      analyzer2.Successor = indexTermination;
-      indexTermination.TrueBranch = improvesQualityBranch2;
+      analyzer2.Successor = indexComparator;
+      indexComparator.Successor = indexTermination;
+      indexTermination.TrueBranch = createChild;
       indexTermination.FalseBranch = null;
-
-      improvesQualityBranch2.TrueBranch = null;
-      improvesQualityBranch2.FalseBranch = createChild;
 
       iterationsCounter.Successor = iterationsComparator;
@@ -281,5 +287,5 @@
 
     public override IOperation Apply() {
-      if (LocalImprovementParameter.ActualValue == null || EvaluatorParameter.ActualValue == null)
+      if (LocalImprovementParameter.ActualValue == null || ShakingOperatorParameter.ActualValue == null)
         return null;
       return base.Apply();
Index: /trunk/sources/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 6042)
@@ -68,6 +68,6 @@
       get { return (ValueLookupParameter<PercentValue>)Parameters["RelativeDifferenceBestKnownToBest"]; }
     }
-    public ValueLookupParameter<VariableCollection> ResultsParameter {
-      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
     }
     #endregion
@@ -106,5 +106,5 @@
       Parameters.Add(new ValueLookupParameter<DoubleValue>("AbsoluteDifferenceBestKnownToBest", "The absolute difference of the best known quality value to the best quality value."));
       Parameters.Add(new ValueLookupParameter<PercentValue>("RelativeDifferenceBestKnownToBest", "The relative difference of the best known quality value to the best quality value."));
-      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The results collection where the analysis values should be stored."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection where the analysis values should be stored."));
       #endregion
 
@@ -166,6 +166,13 @@
     private void AfterDeserialization() {
       Initialize();
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (Parameters["Results"] is ValueLookupParameter<VariableCollection>) {
+        Parameters.Remove("Results");
+        Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The results collection where the analysis values should be stored."));
+      }
+      #endregion
     }
-    
+
     private void Initialize() {
       QualityParameter.DepthChanged += new EventHandler(QualityParameter_DepthChanged);
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj	(revision 6042)
@@ -12,5 +12,6 @@
     <AssemblyName>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
     <SignAssembly>true</SignAssembly>
@@ -118,4 +119,5 @@
     <Compile Include="HeuristicLabEncodingsBinaryVectorEncodingPlugin.cs" />
     <Compile Include="BinaryVector.cs" />
+    <Compile Include="Interfaces\IBinaryVectorMultiNeighborhoodShakingOperator.cs" />
     <Compile Include="Interfaces\IOneBitflipMoveOperator.cs" />
     <Compile Include="Interfaces\IBinaryVectorCreator.cs" />
@@ -140,4 +142,5 @@
     <Compile Include="Moves\OneIndexMove.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperators\BinaryVectorShakingOperator.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -200,4 +203,5 @@
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/Interfaces/IBinaryVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,28 @@
+﻿#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.Core;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  public interface IBinaryVectorMultiNeighborhoodShakingOperator : IBinaryVectorOperator {
+    ILookupParameter<BinaryVector> BinaryVectorParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/ShakingOperators/BinaryVectorShakingOperator.cs	(revision 6042)
@@ -0,0 +1,84 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.BinaryVectorEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("BinaryVectorShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class BinaryVectorShakingOperator : ShakingOperator<IBinaryVectorManipulator>, IBinaryVectorMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<BinaryVector> BinaryVectorParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["BinaryVector"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected BinaryVectorShakingOperator(bool deserializing) : base(deserializing) { }
+    protected BinaryVectorShakingOperator(BinaryVectorShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryVectorShakingOperator(this, cloner);
+    }
+    public BinaryVectorShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<BinaryVector>("BinaryVector", "The binary vector to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IBinaryVectorManipulator shaker in ApplicationManager.Manager.GetInstances<IBinaryVectorManipulator>().OrderBy(x => x.Name))
+        Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IBinaryVectorManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IBinaryVectorManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IBinaryVectorManipulator op in items.Select(x => x.Value).OfType<IBinaryVectorManipulator>())
+          op.BinaryVectorParameter.ActualName = BinaryVectorParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLab.Encodings.IntegerVectorEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLab.Encodings.IntegerVectorEncoding-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLab.Encodings.IntegerVectorEncoding-3.3.csproj	(revision 6042)
@@ -12,5 +12,6 @@
     <AssemblyName>HeuristicLab.Encodings.IntegerVectorEncoding-3.3</AssemblyName>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <FileAlignment>512</FileAlignment>
     <SignAssembly>true</SignAssembly>
@@ -117,4 +118,5 @@
     <Compile Include="Interfaces\IIntegerVectorCrossover.cs" />
     <Compile Include="Interfaces\IIntegerVectorManipulator.cs" />
+    <Compile Include="Interfaces\IIntegerVectorMultiNeighborhoodShakingOperator.cs" />
     <Compile Include="Interfaces\IIntegerVectorOperator.cs" />
     <Compile Include="IntegerVectorCrossover.cs" />
@@ -126,4 +128,5 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="IntegerVectorCreator.cs" />
+    <Compile Include="ShakingOperators\IntegerVectorShakingOperator.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -147,4 +150,8 @@
       <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">
Index: /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLabEncodingsIntegerVectorEncodingPlugin.cs.frame
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLabEncodingsIntegerVectorEncodingPlugin.cs.frame	(revision 6041)
+++ /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/HeuristicLabEncodingsIntegerVectorEncodingPlugin.cs.frame	(revision 6042)
@@ -34,4 +34,5 @@
   [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")]
Index: /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/Interfaces/IIntegerVectorMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/Interfaces/IIntegerVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/Interfaces/IIntegerVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,28 @@
+﻿#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.Core;
+
+namespace HeuristicLab.Encodings.IntegerVectorEncoding {
+  public interface IIntegerVectorMultiNeighborhoodShakingOperator : IIntegerVectorOperator {
+    ILookupParameter<IntegerVector> IntegerVectorParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/ShakingOperators/IntegerVectorShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/ShakingOperators/IntegerVectorShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.IntegerVectorEncoding/3.3/ShakingOperators/IntegerVectorShakingOperator.cs	(revision 6042)
@@ -0,0 +1,84 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.IntegerVectorEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("IntegerVectorShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class IntegerVectorShakingOperator : ShakingOperator<IIntegerVectorManipulator>, IIntegerVectorMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<IntegerVector> IntegerVectorParameter {
+      get { return (ILookupParameter<IntegerVector>)Parameters["IntegerVector"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected IntegerVectorShakingOperator(bool deserializing) : base(deserializing) { }
+    protected IntegerVectorShakingOperator(IntegerVectorShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IntegerVectorShakingOperator(this, cloner);
+    }
+    public IntegerVectorShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<IntegerVector>("IntegerVector", "The integer vector to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IIntegerVectorManipulator shaker in ApplicationManager.Manager.GetInstances<IIntegerVectorManipulator>().OrderBy(x => x.Name))
+        Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IIntegerVectorManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IIntegerVectorManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IIntegerVectorManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IIntegerVectorManipulator op in items.Select(x => x.Value).OfType<IIntegerVectorManipulator>())
+          op.IntegerVectorParameter.ActualName = IntegerVectorParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 6042)
@@ -19,5 +19,6 @@
     </UpgradeBackupLocation>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
@@ -118,4 +119,5 @@
     <Compile Include="Crossovers\PositionBasedCrossover.cs" />
     <Compile Include="HeuristicLabEncodingsPermutationEncodingPlugin.cs" />
+    <Compile Include="Interfaces\IPermutationMultiNeighborhoodShakingOperator.cs" />
     <Compile Include="Interfaces\IPermutationSwap2MoveOperator.cs" />
     <Compile Include="Interfaces\IPermutationCreator.cs" />
@@ -183,4 +185,5 @@
     <Compile Include="PermutationTypes.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperators\PermutationShakingOperator.cs" />
   </ItemGroup>
   <ItemGroup>
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Interfaces/IPermutationMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,29 @@
+﻿#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.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  public interface IPermutationMultiNeighborhoodShakingOperator : IMultiNeighborhoodShakingOperator, IPermutationOperator {
+    ILookupParameter<Permutation> PermutationParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/ShakingOperators/PermutationShakingOperator.cs	(revision 6042)
@@ -0,0 +1,84 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.PermutationEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("PermutationShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class PermutationShakingOperator : ShakingOperator<IPermutationManipulator>, IPermutationMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<Permutation> PermutationParameter {
+      get { return (ILookupParameter<Permutation>)Parameters["Permutation"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected PermutationShakingOperator(bool deserializing) : base(deserializing) { }
+    protected PermutationShakingOperator(PermutationShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PermutationShakingOperator(this, cloner);
+    }
+    public PermutationShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<Permutation>("Permutation", "The permutation to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IPermutationManipulator shaker in ApplicationManager.Manager.GetInstances<IPermutationManipulator>().OrderBy(x => x.Name))
+        if (!(shaker is MultiPermutationManipulator)) Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IPermutationManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IPermutationManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IPermutationManipulator op in items.Select(x => x.Value).OfType<IPermutationManipulator>())
+          op.PermutationParameter.ActualName = PermutationParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/HeuristicLab.Encodings.RealVectorEncoding-3.3.csproj	(revision 6042)
@@ -104,4 +104,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Interfaces\IRealVectorMultiNeighborhoodShakingOperator.cs" />
     <Compile Include="ParticleOperators\RealVectorParticleCreator.cs" />
     <Compile Include="Crossovers\BlendAlphaBetaCrossover.cs" />
@@ -168,4 +169,5 @@
     <Compile Include="Manipulators\UniformOnePositionManipulator.cs" />
     <Compile Include="ReflectiveBoundsChecker.cs" />
+    <Compile Include="ShakingOperators\RealVectorShakingOperator.cs" />
     <Compile Include="StrategyParameters\StdDevStrategyVectorCreator.cs" />
     <Compile Include="StrategyParameters\StdDevStrategyVectorCrossover.cs" />
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/Interfaces/IRealVectorMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,28 @@
+﻿#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.Core;
+
+namespace HeuristicLab.Encodings.RealVectorEncoding {
+  public interface IRealVectorMultiNeighborhoodShakingOperator : IRealVectorOperator {
+    ILookupParameter<RealVector> RealVectorParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ShakingOperators/RealVectorShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ShakingOperators/RealVectorShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Encodings.RealVectorEncoding/3.3/ShakingOperators/RealVectorShakingOperator.cs	(revision 6042)
@@ -0,0 +1,85 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.RealVectorEncoding {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("RealVectorShakingOperator", "A shaking operator for VNS which uses available manipulation operators to perform the shaking.")]
+  [StorableClass]
+  public class RealVectorShakingOperator : ShakingOperator<IRealVectorManipulator>, IRealVectorMultiNeighborhoodShakingOperator, IStochasticOperator {
+
+    public ILookupParameter<RealVector> RealVectorParameter {
+      get { return (ILookupParameter<RealVector>)Parameters["RealVector"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    [StorableConstructor]
+    protected RealVectorShakingOperator(bool deserializing) : base(deserializing) { }
+    protected RealVectorShakingOperator(RealVectorShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RealVectorShakingOperator(this, cloner);
+    }
+    public RealVectorShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<RealVector>("RealVector", "The real vector to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      foreach (IRealVectorManipulator shaker in ApplicationManager.Manager.GetInstances<IRealVectorManipulator>().OrderBy(x => x.Name))
+        if (!(shaker is MultiRealVectorManipulator)
+          && !(shaker is ISelfAdaptiveManipulator)) Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IRealVectorManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IRealVectorManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IRealVectorManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IRealVectorManipulator op in items.Select(x => x.Value).OfType<IRealVectorManipulator>())
+          op.RealVectorParameter.ActualName = RealVectorParameter.Name;
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 6042)
@@ -19,5 +19,6 @@
     </UpgradeBackupLocation>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
@@ -109,4 +110,5 @@
     <Compile Include="MultiObjective\FastNonDominatedSort.cs" />
     <Compile Include="MultiObjective\RankAndCrowdingSorter.cs" />
+    <Compile Include="ShakingOperator.cs" />
     <Compile Include="UserDefinedCrossover.cs" />
     <Compile Include="UserDefinedEvaluator.cs" />
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 6042)
@@ -51,5 +51,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>("LeftSide", "The left side of the comparison."));
       Parameters.Add(new ValueLookupParameter<DoubleValue>("RightSide", "The right side of the comparison."));
-      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison."));
+      Parameters.Add(new LookupParameter<BoolValue>("Result", "The result of the comparison, true if the quality on the LeftSide is better than the quality on the RightSide."));
       Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
     }
Index: /trunk/sources/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 6042)
@@ -0,0 +1,73 @@
+﻿#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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Operators {
+  /// <summary>
+  /// A shaking operator for VNS.
+  /// </summary>
+  [Item("ShakingOperator", "A shaking operator for VNS that can be filled with arbitrary manipulation operators.")]
+  [StorableClass]
+  public class ShakingOperator<T> : CheckedMultiOperator<T>, IMultiNeighborhoodShakingOperator where T : class, IManipulator {
+
+    public IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["CurrentNeighborhoodIndex"]; }
+    }
+
+    public ILookupParameter<IntValue> NeighborhoodCountParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["NeighborhoodCount"]; }
+    }
+
+    [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>("CurrentNeighborhoodIndex", "The index of the operator that should be applied (k)."));
+      Parameters.Add(new LookupParameter<IntValue>("NeighborhoodCount", "The number of operators that are available."));
+    }
+
+    public override IOperation Apply() {
+      if (NeighborhoodCountParameter.ActualValue == null)
+        NeighborhoodCountParameter.ActualValue = new IntValue(Operators.CheckedItems.Count());
+      else NeighborhoodCountParameter.ActualValue.Value = Operators.CheckedItems.Count();
+
+      int index = CurrentNeighborhoodIndexParameter.ActualValue.Value;
+      var shaker = base.Operators.CheckedItems.SingleOrDefault(x => x.Index == index);
+
+      OperationCollection next = new OperationCollection(base.Apply());
+      if (shaker.Value != null)
+        next.Insert(0, ExecutionContext.CreateChildOperation(shaker.Value));
+
+      return next;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 6042)
@@ -120,4 +120,6 @@
     <Compile Include="Interfaces\ILocalParticleUpdater.cs" />
     <Compile Include="Algorithms\HeuristicOptimizationAlgorithm.cs" />
+    <Compile Include="Interfaces\IMultiNeighborhoodShakingOperator.cs" />
+    <Compile Include="MoveHelper.cs" />
     <Compile Include="Problems\MultiObjectiveHeuristicOptimizationProblem.cs" />
     <Compile Include="Problems\HeuristicOptimizationProblem.cs" />
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/ILocalImprovementOperator.cs	(revision 6042)
@@ -21,13 +21,14 @@
 
 using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 using HeuristicLab.Core;
-using HeuristicLab.Optimization;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Optimization {
-  public interface ILocalImprovementOperator: IOperator {
-    void OnProblemChanged(IProblem problem);
+  public interface ILocalImprovementOperator : IOperator {
+    Type ProblemType { get; }
+    IProblem Problem { get; set; }
+    IValueLookupParameter<IntValue> MaximumIterationsParameter { get; }
+    ILookupParameter<IntValue> EvaluatedSolutionsParameter { get; }
+    ILookupParameter<ResultCollection> ResultsParameter { get; }
   }
 }
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,30 @@
+﻿#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.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Optimization {
+  public interface IMultiNeighborhoodShakingOperator : IOperator {
+    IValueLookupParameter<IntValue> CurrentNeighborhoodIndexParameter { get; }
+    ILookupParameter<IntValue> NeighborhoodCountParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimization/3.3/MoveHelper.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/MoveHelper.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/MoveHelper.cs	(revision 6042)
@@ -0,0 +1,66 @@
+﻿#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 HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization {
+  /// <summary>
+  /// This class provides some methods useful when dealing with moves, such as getting compatible move makers to a move generator.
+  /// Compatibility is generally ensured in that both the generator and the move maker implement the same specific interface which is derived from IMoveOperator
+  /// </summary>
+  public static class MoveHelper {
+
+    public static IEnumerable<IMoveMaker> GetCompatibleMoveMakers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<IMoveMaker>(generator, operators);
+    }
+
+    public static IEnumerable<ISingleObjectiveMoveEvaluator> GetCompatibleSingleObjectiveMoveEvaluators(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ISingleObjectiveMoveEvaluator>(generator, operators);
+    }
+
+    public static IEnumerable<ITabuChecker> GetCompatibleTabuChekers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ITabuChecker>(generator, operators);
+    }
+
+    public static IEnumerable<ITabuMaker> GetCompatibleTabuMakers(IMoveGenerator generator, IEnumerable<IOperator> operators) {
+      return GetCompatibleOperators<ITabuMaker>(generator, operators);
+    }
+
+    private static IEnumerable<T> GetCompatibleOperators<T>(IMoveGenerator generator, IEnumerable<IOperator> operators) where T : IOperator {
+      foreach (Type type in GetMostSpecificMoveOperatorTypes(generator)) {
+        foreach (T op in operators.Where(x => type.IsAssignableFrom(x.GetType())).OfType<T>())
+          yield return op;
+      }
+    }
+
+    private static List<Type> GetMostSpecificMoveOperatorTypes(IMoveGenerator generator) {
+      List<Type> moveTypes = generator.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);
+      }
+      return moveTypes;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Optimizer/3.3/HeuristicLab.Optimizer-3.3.csproj	(revision 6042)
@@ -115,5 +115,4 @@
     <EmbeddedResource Include="Documents\SGP_SymbClass_Mammographic.hl" />
     <EmbeddedResource Include="Documents\SGP_SymbReg.hl" />
-    <EmbeddedResource Include="Documents\VNS_TSP.hl" />
     <None Include="HeuristicLabOptimizerPlugin.cs.frame" />
     <Compile Include="CreateExperimentDialog.cs">
Index: /trunk/sources/HeuristicLab.Problems.Knapsack/3.3/KnapsackProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.Knapsack/3.3/KnapsackProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.Knapsack/3.3/KnapsackProblem.cs	(revision 6042)
@@ -339,4 +339,6 @@
         op.ValuesParameter.ActualName = ValuesParameter.Name;
       }
+      foreach (var op in Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>())
+        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
     }
     #endregion
Index: /trunk/sources/HeuristicLab.Problems.OneMax/3.3/OnemaxProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.OneMax/3.3/OnemaxProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.OneMax/3.3/OnemaxProblem.cs	(revision 6042)
@@ -262,4 +262,6 @@
         op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
       }
+      foreach (var op in Operators.OfType<IBinaryVectorMultiNeighborhoodShakingOperator>())
+        op.BinaryVectorParameter.ActualName = SolutionCreator.BinaryVectorParameter.ActualName;
     }
     #endregion
Index: /trunk/sources/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.QuadraticAssignment/3.3/QuadraticAssignmentProblem.cs	(revision 6042)
@@ -287,4 +287,6 @@
         }
       }
+      foreach (var op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>())
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.TestFunctions/3.3/SingleObjectiveTestFunctionProblem.cs	(revision 6042)
@@ -417,4 +417,6 @@
         op.MaximizationParameter.ActualName = MaximizationParameter.Name;
       }
+      foreach (var op in Operators.OfType<IRealVectorMultiNeighborhoodShakingOperator>())
+        op.RealVectorParameter.ActualName = SolutionCreator.RealVectorParameter.ActualName;
     }
     private void UpdateStrategyVectorBounds() {
Index: /trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.TravelingSalesman/3.3/TravelingSalesmanProblem.cs	(revision 6042)
@@ -389,4 +389,6 @@
       foreach (IPermutationTranslocationMoveOperator op in Operators.OfType<IPermutationTranslocationMoveOperator>())
         op.TranslocationMoveParameter.ActualName = translocationMove;
+      foreach (IPermutationMultiNeighborhoodShakingOperator op in Operators.OfType<IPermutationMultiNeighborhoodShakingOperator>())
+        op.PermutationParameter.ActualName = SolutionCreator.PermutationParameter.ActualName;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 6042)
@@ -19,5 +19,6 @@
     </UpgradeBackupLocation>
     <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
-    <TargetFrameworkProfile></TargetFrameworkProfile>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
     <PublishUrl>publish\</PublishUrl>
     <Install>true</Install>
@@ -111,4 +112,6 @@
     <Compile Include="Analyzers\BestVRPToursMemorizer.cs" />
     <Compile Include="Analyzers\BestVRPSolutionAnalyzer.cs" />
+    <Compile Include="Interfaces\IVRPMultiNeighborhoodShakingOperator.cs" />
+    <Compile Include="ShakingOperators\VehicleRoutingShakingOperator.cs" />
     <Compile Include="SolutionParser.cs" />
     <Compile Include="Encodings\Alba\Crossovers\AlbaPermutationCrossover.cs" />
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Interfaces/IVRPMultiNeighborhoodShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Interfaces/IVRPMultiNeighborhoodShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Interfaces/IVRPMultiNeighborhoodShakingOperator.cs	(revision 6042)
@@ -0,0 +1,29 @@
+﻿#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.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  public interface IVRPMultiNeighborhoodShakingOperator : IMultiNeighborhoodShakingOperator, IVRPOperator {
+    ILookupParameter<IVRPEncoding> VRPToursParameter { get; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/ShakingOperators/VehicleRoutingShakingOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/ShakingOperators/VehicleRoutingShakingOperator.cs	(revision 6042)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/ShakingOperators/VehicleRoutingShakingOperator.cs	(revision 6042)
@@ -0,0 +1,148 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.VehicleRouting.Encodings.General;
+
+namespace HeuristicLab.Problems.VehicleRouting {
+  [Item("VRPShakingOperator", "A shaking operator for VNS that applies available mutation operators.")]
+  [StorableClass]
+  public class VehicleRoutingShakingOperator : ShakingOperator<IVRPManipulator>, IVRPMultiNeighborhoodShakingOperator, IStochasticOperator {
+    #region Parameters
+    public ILookupParameter<IVRPEncoding> VRPToursParameter {
+      get { return (ILookupParameter<IVRPEncoding>)Parameters["VRPTours"]; }
+    }
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<DoubleMatrix> CoordinatesParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["Coordinates"]; }
+    }
+
+    public int Cities {
+      get {
+        if (CoordinatesParameter.ActualValue != null)
+          return CoordinatesParameter.ActualValue.Rows;
+        else return 0;
+      }
+    }
+
+    public ILookupParameter<DoubleMatrix> DistanceMatrixParameter {
+      get { return (ILookupParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public ILookupParameter<BoolValue> UseDistanceMatrixParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["UseDistanceMatrix"]; }
+    }
+
+    public ILookupParameter<IntValue> VehiclesParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["Vehicles"]; }
+    }
+
+    public ILookupParameter<DoubleValue> CapacityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Capacity"]; }
+    }
+
+    public ILookupParameter<DoubleArray> DemandParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["Demand"]; }
+    }
+
+    public ILookupParameter<DoubleArray> ReadyTimeParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["ReadyTime"]; }
+    }
+
+    public ILookupParameter<DoubleArray> DueTimeParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["DueTime"]; }
+    }
+
+    public ILookupParameter<DoubleArray> ServiceTimeParameter {
+      get { return (ILookupParameter<DoubleArray>)Parameters["ServiceTime"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected VehicleRoutingShakingOperator(bool deserializing) : base(deserializing) { }
+    protected VehicleRoutingShakingOperator(VehicleRoutingShakingOperator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VehicleRoutingShakingOperator(this, cloner);
+    }
+    public VehicleRoutingShakingOperator()
+      : base() {
+      Parameters.Add(new LookupParameter<IVRPEncoding>("VRPTours", "The vrp tour encoding to shake."));
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator that will be used for stochastic shaking operators."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("Coordinates", "The coordinates of the cities."));
+      Parameters.Add(new LookupParameter<DoubleMatrix>("DistanceMatrix", "The matrix which contains the distances between the cities."));
+      Parameters.Add(new LookupParameter<BoolValue>("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false."));
+      Parameters.Add(new LookupParameter<IntValue>("Vehicles", "The number of vehicles."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Capacity", "The capacity of each vehicle."));
+      Parameters.Add(new LookupParameter<DoubleArray>("Demand", "The demand of each customer."));
+      Parameters.Add(new LookupParameter<DoubleArray>("ReadyTime", "The ready time of each customer."));
+      Parameters.Add(new LookupParameter<DoubleArray>("DueTime", "The due time of each customer."));
+      Parameters.Add(new LookupParameter<DoubleArray>("ServiceTime", "The service time of each customer."));
+
+      foreach (IVRPManipulator shaker in ApplicationManager.Manager.GetInstances<IVRPManipulator>().OrderBy(x => x.Name))
+        if (!(shaker is MultiVRPSolutionManipulator)) Operators.Add(shaker);
+    }
+
+    #region Wiring of some parameters
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IVRPManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IVRPManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeOperators(e.Items);
+    }
+
+    private void ParameterizeOperators(IEnumerable<IndexedItem<IVRPManipulator>> items) {
+      if (items.Any()) {
+        foreach (IStochasticOperator op in items.Select(x => x.Value).OfType<IStochasticOperator>())
+          op.RandomParameter.ActualName = RandomParameter.Name;
+        foreach (IVRPManipulator op in items.Select(x => x.Value).OfType<IVRPManipulator>()) {
+          op.VRPToursParameter.ActualName = VRPToursParameter.Name;
+          if (op.CoordinatesParameter != null) op.CoordinatesParameter.ActualName = CoordinatesParameter.Name;
+          if (op.DistanceMatrixParameter != null) op.DistanceMatrixParameter.ActualName = DistanceMatrixParameter.Name;
+          if (op.UseDistanceMatrixParameter != null) op.UseDistanceMatrixParameter.ActualName = UseDistanceMatrixParameter.Name;
+          if (op.VehiclesParameter != null) op.VehiclesParameter.ActualName = VehiclesParameter.Name;
+          if (op.CapacityParameter != null) op.CapacityParameter.ActualName = CapacityParameter.Name;
+          if (op.DemandParameter != null) op.DemandParameter.ActualName = DemandParameter.Name;
+          if (op.ReadyTimeParameter != null) op.ReadyTimeParameter.ActualName = ReadyTimeParameter.Name;
+          if (op.DueTimeParameter != null) op.DueTimeParameter.ActualName = DueTimeParameter.Name;
+          if (op.ServiceTimeParameter != null) op.ServiceTimeParameter.ActualName = ServiceTimeParameter.Name;
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VehicleRoutingProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VehicleRoutingProblem.cs	(revision 6041)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VehicleRoutingProblem.cs	(revision 6042)
@@ -607,4 +607,8 @@
         op.VRPToursParameter.ActualName = SolutionCreator.VRPToursParameter.ActualName;
       }
+
+      foreach (var op in Operators.OfType<IVRPMultiNeighborhoodShakingOperator>()) {
+        op.VRPToursParameter.ActualName = SolutionCreator.VRPToursParameter.ActualName;
+      }
     }
     private void ClearDistanceMatrix() {
Index: /trunk/tools/HL3Snippets/HL3.BackwardsCompatibility.snippet
===================================================================
--- /trunk/tools/HL3Snippets/HL3.BackwardsCompatibility.snippet	(revision 6042)
+++ /trunk/tools/HL3Snippets/HL3.BackwardsCompatibility.snippet	(revision 6042)
@@ -0,0 +1,40 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
+  <CodeSnippet Format="1.0.0">
+    <Header>
+      <Title>HL3.BackwardsCompatibility</Title>
+      <Author>Andreas Beham</Author>
+      <Description>Adds the backwards compatibility comment and region</Description>
+      <HelpUrl>https://dev.heuristiclab.com/trac/hl/core/wiki/DevelopersCodeSnippets</HelpUrl>
+      <SnippetTypes>
+        <SnippetType>Expansion</SnippetType>
+      </SnippetTypes>
+      <Keywords />
+      <Shortcut>hl3BackwardsCompatibility</Shortcut>
+    </Header>
+    <Snippet>
+      <References />
+      <Imports />
+      <Declarations>
+        <Literal Editable="true">
+          <ID>currentversion</ID>
+          <Type />
+          <ToolTip>Enter the current major.minor version number</ToolTip>
+          <Default>3.3</Default>
+          <Function></Function>
+        </Literal>
+        <Literal Editable="true">
+          <ID>nextversion</ID>
+          <Type />
+          <ToolTip>Enter the next major.minor version number</ToolTip>
+          <Default>3.4</Default>
+          <Function></Function>
+        </Literal>
+      </Declarations>
+      <Code Language="csharp" Kind="" Delimiter="$"><![CDATA[// BackwardsCompatibility$currentversion$
+      #region Backwards compatible code, remove with $nextversion$
+      
+      #endregion]]></Code>
+    </Snippet>
+  </CodeSnippet>
+</CodeSnippets>
