Index: branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovement.cs
===================================================================
--- branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovement.cs	(revision 5622)
+++ branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovement.cs	(revision 5642)
@@ -44,12 +44,12 @@
     private LocalSearchMainLoop loop;
     
-    private /*Constrained*/ValueParameter<IMoveGenerator> MoveGeneratorParameter {
-      get { return (/*Constrained*/ValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
-    }
-    private /*Constrained*/ValueParameter<IMoveMaker> MoveMakerParameter {
-      get { return (/*Constrained*/ValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
-    }
-    private /*Constrained*/ValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
-      get { return (/*Constrained*/ValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
+    private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
+      get { return (ConstrainedValueParameter<IMoveGenerator>)Parameters["MoveGenerator"]; }
+    }
+    private ConstrainedValueParameter<IMoveMaker> MoveMakerParameter {
+      get { return (ConstrainedValueParameter<IMoveMaker>)Parameters["MoveMaker"]; }
+    }
+    private ConstrainedValueParameter<ISingleObjectiveMoveEvaluator> MoveEvaluatorParameter {
+      get { return (ConstrainedValueParameter<ISingleObjectiveMoveEvaluator>)Parameters["MoveEvaluator"]; }
     }
     private ValueParameter<IntValue> MaximumIterationsParameter {
@@ -80,8 +80,13 @@
 
     [StorableConstructor]
-    protected LocalSearchImprovement(bool deserializing) : base(deserializing) { }
+    protected LocalSearchImprovement(bool deserializing) : base(deserializing) {}
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      Initialize();
+    }
     protected LocalSearchImprovement(LocalSearchImprovement original, Cloner cloner)
       : base(original, cloner) {
         this.loop = cloner.Clone(original.loop);
+        Initialize();
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -92,20 +97,39 @@
         loop = new LocalSearchMainLoop(new BoolValue(true));
 
-        Parameters.Add(new /*Constrained*/ValueParameter<IMoveGenerator>("MoveGenerator", "The operator used to generate moves to the neighborhood of the current solution."));
-        Parameters.Add(new /*Constrained*/ValueParameter<IMoveMaker>("MoveMaker", "The operator used to perform a move."));
-        Parameters.Add(new /*Constrained*/ValueParameter<ISingleObjectiveMoveEvaluator>("MoveEvaluator", "The operator used to evaluate a move."));
+        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(1000)));
         Parameters.Add(new ValueParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(100)));
         Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
         Parameters.Add(new LookupParameter<IOperator>("Analyzer", "The operator used to analyze the solution."));
+
+        Initialize();
+    }
+
+    private void Initialize() {
+      MoveGeneratorParameter.ValueChanged += new EventHandler(MoveGeneratorParameter_ValueChanged);
     }
 
     public void Parameterize(IProblem problem) {
       UpdateMoveOperators(problem);
+      ChooseMoveOperators();
+
+      ParameterizeMoveGenerators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveEvaluators(problem as ISingleObjectiveProblem);
+      ParameterizeMoveMakers(problem as ISingleObjectiveProblem);
+    }
+
+    void MoveGeneratorParameter_ValueChanged(object sender, EventArgs e) {
+      ChooseMoveOperators();
     }
 
     private void UpdateMoveOperators(IProblem problem) {
-     /* IMoveGenerator oldMoveGenerator = MoveGenerator;
-      MoveGeneratorParameter.ValidValues.Clear();
+      IMoveGenerator oldMoveGenerator = MoveGenerator;
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      ClearMoveParameters();
+
       if (problem != null) {
         foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
@@ -127,5 +151,4 @@
       }
 
-      IMoveMaker oldMoveMaker = MoveMaker;
       if (oldMoveMaker != null) {
         IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
@@ -133,14 +156,69 @@
       }
 
-      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
       if (oldMoveEvaluator != null) {
         ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
         if (me != null) MoveEvaluator = me;
-      }*/
+      }
+    }
+
+    private void ChooseMoveOperators() {
+      IMoveMaker oldMoveMaker = MoveMaker;
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+
+      if (MoveGenerator != null) {
+        List<Type> moveTypes = MoveGenerator.GetType().GetInterfaces().Where(x => typeof(IMoveOperator).IsAssignableFrom(x)).ToList();
+        foreach (Type type in moveTypes.ToList()) {
+          if (moveTypes.Any(t => t != type && type.IsAssignableFrom(t)))
+            moveTypes.Remove(type);
+        }
+        List<IMoveMaker> validMoveMakers = new List<IMoveMaker>();
+        List<ISingleObjectiveMoveEvaluator> validMoveEvaluators = new List<ISingleObjectiveMoveEvaluator>();
+
+        foreach (Type type in moveTypes) {
+          var moveMakers = MoveMakerParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (IMoveMaker moveMaker in moveMakers)
+            validMoveMakers.Add(moveMaker);
+
+          var moveEvaluators = MoveEvaluatorParameter.ValidValues.Where(x => type.IsAssignableFrom(x.GetType())).OrderBy(x => x.Name);
+          foreach (ISingleObjectiveMoveEvaluator moveEvaluator in moveEvaluators)
+            validMoveEvaluators.Add(moveEvaluator);
+        }
+        if (oldMoveMaker != null) {
+          IMoveMaker mm = validMoveMakers.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+          if (mm != null) MoveMaker = mm;
+          else MoveMaker = validMoveMakers.FirstOrDefault();
+        } 
+
+        if (oldMoveEvaluator != null) {
+          ISingleObjectiveMoveEvaluator me = validMoveEvaluators.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+          if (me != null) MoveEvaluator = me;
+          else MoveEvaluator = validMoveEvaluators.FirstOrDefault();
+        } 
+      }
     }
 
     private void ClearMoveParameters() {
-      /*MoveMakerParameter.ValidValues.Clear();
-      MoveEvaluatorParameter.ValidValues.Clear();*/
+      MoveGeneratorParameter.ValidValues.Clear();
+      MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();
+    }
+
+    private void ParameterizeMoveGenerators(ISingleObjectiveProblem problem) {
+      if (problem != null) {
+        foreach (IMultiMoveGenerator generator in problem.Operators.OfType<IMultiMoveGenerator>())
+          generator.SampleSizeParameter.ActualName = SampleSizeParameter.Name;
+      }
+    }
+    private void ParameterizeMoveEvaluators(ISingleObjectiveProblem problem) {
+      foreach (ISingleObjectiveMoveEvaluator op in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+      }
+    }
+    private void ParameterizeMoveMakers(ISingleObjectiveProblem problem) {
+      foreach (IMoveMaker op in problem.Operators.OfType<IMoveMaker>()) {
+        op.QualityParameter.ActualName = problem.Evaluator.QualityParameter.ActualName;
+        if (MoveEvaluator != null)
+          op.MoveQualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+      }
     }
 
