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 5830)
+++ 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 5830)
+++ 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: trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/IShakingOperator.cs	(revision 5830)
+++ 	(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: trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 5830)
+++ 	(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 5830)
+++ 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 5830)
+++ 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();
