Index: branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs
===================================================================
--- branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovement.cs	(revision 5642)
+++ branches/VNS/HeuristicLab.Algorithms.LocalSearch/3.3/LocalSearchImprovementOperator.cs	(revision 5735)
@@ -33,4 +33,5 @@
 using HeuristicLab.Optimization;
 using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Analysis;
 
 namespace HeuristicLab.Algorithms.LocalSearch {
@@ -38,9 +39,12 @@
   /// A local search improvement operator.
   /// </summary>
-  [Item("LocalSearchImprovement", "A local search improvement operator.")]
+  [Item("LocalSearchImprovementOperator", "A local search improvement operator.")]
   [StorableClass]
-  public class LocalSearchImprovement: SingleSuccessorOperator, ILocalImprovement {
+  public class LocalSearchImprovementOperator: SingleSuccessorOperator, ILocalImprovementOperator {
     [Storable]
     private LocalSearchMainLoop loop;
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
     
     private ConstrainedValueParameter<IMoveGenerator> MoveGeneratorParameter {
@@ -62,6 +66,6 @@
       get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
     }
-    public LookupParameter<IOperator> AnalyzerParameter {
-      get { return (LookupParameter<IOperator>)Parameters["Analyzer"]; }
+    public ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
     }
 
@@ -78,30 +82,41 @@
       set { MoveEvaluatorParameter.Value = value; }
     }
+    public MultiAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+      set { AnalyzerParameter.Value = value; }
+    }
 
     [StorableConstructor]
-    protected LocalSearchImprovement(bool deserializing) : base(deserializing) {}
+    protected LocalSearchImprovementOperator(bool deserializing) : base(deserializing) {}
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
       Initialize();
     }
-    protected LocalSearchImprovement(LocalSearchImprovement original, Cloner cloner)
+    protected LocalSearchImprovementOperator(LocalSearchImprovementOperator original, Cloner cloner)
       : base(original, cloner) {
         this.loop = cloner.Clone(original.loop);
+        this.qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
         Initialize();
     }
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new LocalSearchImprovement(this, cloner);
-    }
-    public LocalSearchImprovement()
+      return new LocalSearchImprovementOperator(this, cloner);
+    }
+    public LocalSearchImprovementOperator()
       : base() {
-        loop = new LocalSearchMainLoop(new BoolValue(true));
+        loop = new LocalSearchMainLoop("LocalIterations", "BestLocalQuality");
+
+        ResultsCollector rc = ((loop.OperatorGraph.InitialOperator as SingleSuccessorOperator).Successor 
+          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(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 ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(150)));
+        Parameters.Add(new ValueParameter<IntValue>("SampleSize", "Number of moves that MultiMoveGenerators should create. This is ignored for Exhaustive- and SingleMoveGenerators.", new IntValue(1500)));
         Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated moves."));
-        Parameters.Add(new LookupParameter<IOperator>("Analyzer", "The operator used to analyze the solution."));
+        Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution.", new MultiAnalyzer()));
 
         Initialize();
@@ -112,5 +127,5 @@
     }
 
-    public void Parameterize(IProblem problem) {
+    public void OnProblemChanged(IProblem problem) {
       UpdateMoveOperators(problem);
       ChooseMoveOperators();
@@ -119,4 +134,30 @@
       ParameterizeMoveEvaluators(problem as ISingleObjectiveProblem);
       ParameterizeMoveMakers(problem as ISingleObjectiveProblem);
+
+      ParameterizeAnalyzers(problem as ISingleObjectiveProblem);
+      UpdateAnalyzers(problem as ISingleObjectiveProblem);
+    }
+
+    void ParameterizeAnalyzers(ISingleObjectiveProblem problem) {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      if (problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = problem.MaximizationParameter.Name;
+        if (MoveEvaluator != null)
+          qualityAnalyzer.QualityParameter.ActualName = MoveEvaluator.MoveQualityParameter.ActualName;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = problem.BestKnownQualityParameter.Name;
+      }
+    }
+
+    void UpdateAnalyzers(ISingleObjectiveProblem problem) {
+      Analyzer.Operators.Clear();
+      if (problem != null) {
+        foreach (IAnalyzer analyzer in problem.Operators.OfType<IAnalyzer>()) {
+          IAnalyzer clone = analyzer.Clone() as IAnalyzer;
+          foreach (IScopeTreeLookupParameter param in clone.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 0;
+          Analyzer.Operators.Add(clone);
+        }
+      }
+      Analyzer.Operators.Add(qualityAnalyzer);
     }
 
@@ -245,30 +286,6 @@
       }
 
-      loop.MoveGeneratorParameter.Value = MoveGeneratorParameter.Value;
-      if (loop.MoveGeneratorParameter.Value != null && loop.MoveGeneratorParameter.Value.Parameters.ContainsKey("SampleSize")) {
-        IParameter parameter = loop.MoveGeneratorParameter.Value.Parameters["SampleSize"];
-        if(parameter is IValueParameter)
-          (parameter as IValueParameter).Value = SampleSizeParameter.Value;
-      }
-      loop.MoveEvaluatorParameter.Value = MoveEvaluatorParameter.Value;
-      loop.MoveMakerParameter.Value = MoveMakerParameter.Value;
-      loop.MaximumIterationsParameter.Value = MaximumIterationsParameter.Value;
       loop.EvaluatedMovesParameter.ActualName = EvaluatedSolutionsParameter.ActualName;
-      if (AnalyzerParameter.ActualValue != null) {
-        loop.AnalyzerParameter.Value = AnalyzerParameter.ActualValue.Clone() as IAnalyzer;
-
-        foreach (IScopeTreeLookupParameter param in loop.AnalyzerParameter.Value.Parameters.OfType<IScopeTreeLookupParameter>())
-          param.Depth = 0;
-
-        if (loop.AnalyzerParameter.Value is IMultiAnalyzer) {
-          foreach (IAnalyzer analyzer in (loop.AnalyzerParameter.Value as IMultiAnalyzer).Operators) {
-            foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
-              param.Depth = 0;
-          }
-        }
-      } else {
-        loop.AnalyzerParameter.Value = null;
-      }
-            
+
       processor.Operators.Add(loop);
       processor.Successor = remover;
@@ -279,5 +296,5 @@
       }
 
-      return ExecutionContext.CreateOperation(processor);
+      return ExecutionContext.CreateChildOperation(processor);
     }
   }
