Index: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj	(revision 5602)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/HeuristicLab.Algorithms.VariableNeighborhoodSearch-3.3.csproj	(revision 5603)
@@ -108,5 +108,10 @@
   <ItemGroup>
     <Compile Include="HeuristicLabAlgorithmsVariableNeighborhoodSearchPlugin.cs" />
+    <Compile Include="ILocalImprovement.cs" />
+    <Compile Include="LocalSearchImprovement.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ShakingOperator.cs" />
+    <Compile Include="VariableNeighborhoodSearch.cs" />
+    <Compile Include="VariableNeighborhoodSearchMainLoop.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -116,4 +121,8 @@
   </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: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ILocalImprovement.cs
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ILocalImprovement.cs	(revision 5603)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ILocalImprovement.cs	(revision 5603)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  public interface ILocalImprovement: IOperator {
+    void Parameterize(IProblem problem);
+  }
+}
Index: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/LocalSearchImprovement.cs
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/LocalSearchImprovement.cs	(revision 5603)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/LocalSearchImprovement.cs	(revision 5603)
@@ -0,0 +1,155 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Algorithms.LocalSearch;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  /// <summary>
+  /// A local search improvement operator.
+  /// </summary>
+  [Item("LocalSearchImprovement", "A local search improvement operator.")]
+  [StorableClass]
+  public class LocalSearchImprovement: SingleSuccessorOperator, ILocalImprovement {
+    [Storable]
+    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 ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private ValueParameter<IntValue> SampleSizeParameter {
+      get { return (ValueParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+    public LookupParameter<IntValue> EvaluatedMovesParameter {
+      get { return (LookupParameter<IntValue>)Parameters["EvaluatedMoves"]; }
+    }
+
+    public IMoveGenerator MoveGenerator {
+      get { return MoveGeneratorParameter.Value; }
+      set { MoveGeneratorParameter.Value = value; }
+    }
+    public IMoveMaker MoveMaker {
+      get { return MoveMakerParameter.Value; }
+      set { MoveMakerParameter.Value = value; }
+    }
+    public ISingleObjectiveMoveEvaluator MoveEvaluator {
+      get { return MoveEvaluatorParameter.Value; }
+      set { MoveEvaluatorParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected LocalSearchImprovement(bool deserializing) : base(deserializing) { }
+    protected LocalSearchImprovement(LocalSearchImprovement original, Cloner cloner)
+      : base(original, cloner) {
+        this.loop = cloner.Clone(original.loop);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LocalSearchImprovement(this, cloner);
+    }
+    public LocalSearchImprovement()
+      : base() {
+        loop = new LocalSearchMainLoop();
+        loop.ResultsParameter.Value = new VariableCollection();
+
+        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 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>("EvaluatedMoves", "The number of evaluated moves."));
+    }
+
+    public void Parameterize(IProblem problem) {
+      UpdateMoveOperators(problem);
+    }
+
+    private void UpdateMoveOperators(IProblem problem) {
+     /* IMoveGenerator oldMoveGenerator = MoveGenerator;
+      MoveGeneratorParameter.ValidValues.Clear();
+      if (problem != null) {
+        foreach (IMoveGenerator generator in problem.Operators.OfType<IMoveGenerator>().OrderBy(x => x.Name))
+          MoveGeneratorParameter.ValidValues.Add(generator);
+
+        foreach (IMoveMaker maker in problem.Operators.OfType<IMoveMaker>().OrderBy(x => x.Name))
+          MoveMakerParameter.ValidValues.Add(maker);
+
+        foreach (ISingleObjectiveMoveEvaluator evaluator in problem.Operators.OfType<ISingleObjectiveMoveEvaluator>().OrderBy(x => x.Name))
+          MoveEvaluatorParameter.ValidValues.Add(evaluator);
+      }
+
+      if (oldMoveGenerator != null) {
+        IMoveGenerator newMoveGenerator = MoveGeneratorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveGenerator.GetType());
+        if (newMoveGenerator != null) MoveGenerator = newMoveGenerator;
+      }
+      if (MoveGenerator == null) {
+        ClearMoveParameters();
+      }
+
+      IMoveMaker oldMoveMaker = MoveMaker;
+      if (oldMoveMaker != null) {
+        IMoveMaker mm = MoveMakerParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveMaker.GetType());
+        if (mm != null) MoveMaker = mm;
+      }
+
+      ISingleObjectiveMoveEvaluator oldMoveEvaluator = MoveEvaluator;
+      if (oldMoveEvaluator != null) {
+        ISingleObjectiveMoveEvaluator me = MoveEvaluatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMoveEvaluator.GetType());
+        if (me != null) MoveEvaluator = me;
+      }*/
+    }
+
+    private void ClearMoveParameters() {
+      /*MoveMakerParameter.ValidValues.Clear();
+      MoveEvaluatorParameter.ValidValues.Clear();*/
+    }
+
+    public override IOperation Apply() {
+      Scope subScope = new Scope();
+      subScope.Parent = ExecutionContext.Scope;
+
+      IAtomicOperation op = ExecutionContext.CreateChildOperation(loop, subScope);
+      op.Operator.Execute((IExecutionContext)op, CancellationToken);
+
+      ExecutionContext.Scope.SubScopes.Remove(subScope);
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 5603)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/ShakingOperator.cs	(revision 5603)
@@ -0,0 +1,81 @@
+﻿#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: CheckedMultiOperator<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 original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ShakingOperator(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 override IOperation Apply() {
+      int index = IndexParameter.ActualValue.Value;    
+      var operators = base.Operators.CheckedItems.ToList();
+
+      IOperator successor = null;
+
+      if (index >= operators.Count || index < 0) {
+        ContinueParameter.ActualValue = new BoolValue(false);
+      } else {
+        ContinueParameter.ActualValue = new BoolValue(true);
+        successor = operators[index].Value;
+      }
+
+      OperationCollection next = new OperationCollection(base.Apply());
+      if (successor != null)
+        next.Insert(0, ExecutionContext.CreateOperation(successor));
+
+      return next;
+    }
+  }
+}
Index: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs	(revision 5603)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearch.cs	(revision 5603)
@@ -0,0 +1,123 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Analysis;
+using HeuristicLab.Random;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  [Item("Variable Neighborhood Search", "A variable neighborhood search algorithm.")]
+  [Creatable("Algorithms")]
+  [StorableClass]
+  public sealed class VariableNeighborhoodSearch : EngineAlgorithm, IStorableContent {
+    public string Filename { get; set; }
+
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(ISingleObjectiveProblem); }
+    }
+    public new ISingleObjectiveProblem Problem {
+      get { return (ISingleObjectiveProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private ValueParameter<IntValue> SeedParameter {
+      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
+    }
+    public /*Constrained*/ValueParameter<ISingleObjectiveEvaluator> EvaluatorParameter {
+      get { return (/*Constrained*/ValueParameter<ISingleObjectiveEvaluator>)Parameters["Evaluator"]; }
+    }
+    private ValueParameter<ILocalImprovement> LocalImprovementParameter {
+      get { return (ValueParameter<ILocalImprovement>)Parameters["LocalImprovement"]; }
+    }
+    private ValueParameter<ShakingOperator> ShakingParameter {
+      get { return (ValueParameter<ShakingOperator>)Parameters["Shaking"]; }
+    }
+    private ValueParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    private ValueParameter<MultiAnalyzer> AnalyzerParameter {
+      get { return (ValueParameter<MultiAnalyzer>)Parameters["Analyzer"]; }
+    }
+    #endregion
+
+    #region Properties
+    private RandomCreator RandomCreator {
+      get { return (RandomCreator)OperatorGraph.InitialOperator; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private VariableNeighborhoodSearch(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+
+    }
+    private VariableNeighborhoodSearch(VariableNeighborhoodSearch original, Cloner cloner)
+      : base(original, cloner) {
+
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableNeighborhoodSearch(this, cloner);
+    }
+    public VariableNeighborhoodSearch()
+      : base() {
+      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new /*Constrained*/ValueParameter<ISingleObjectiveEvaluator>("Evaluator", "The operator used to evaluate the solutions."));
+      Parameters.Add(new ValueParameter<ILocalImprovement>("LocalImprovement", "The local improvement operation", new LocalSearchImprovement()));
+      Parameters.Add(new ValueParameter<ShakingOperator>("Shaking", "The shaking operation", new ShakingOperator()));
+      Parameters.Add(new ValueParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed.", new IntValue(1000)));
+      Parameters.Add(new ValueParameter<MultiAnalyzer>("Analyzer", "The operator used to analyze the solution and moves.", new MultiAnalyzer()));
+
+      RandomCreator randomCreator = new RandomCreator();
+      SolutionsCreator solutionsCreator = new SolutionsCreator();
+      VariableCreator variableCreator = new VariableCreator();
+      ResultsCollector resultsCollector = new ResultsCollector();
+      VariableNeighborhoodSearchMainLoop mainLoop = new VariableNeighborhoodSearchMainLoop();
+      OperatorGraph.InitialOperator = randomCreator;
+
+      randomCreator.RandomParameter.ActualName = "Random";
+      randomCreator.SeedParameter.ActualName = SeedParameter.Name;
+      randomCreator.SeedParameter.Value = null;
+      randomCreator.SetSeedRandomlyParameter.ActualName = SetSeedRandomlyParameter.Name;
+      randomCreator.SetSeedRandomlyParameter.Value = null;
+      randomCreator.Successor = solutionsCreator;
+
+      solutionsCreator.NumberOfSolutions = new IntValue(1);
+      solutionsCreator.Successor = variableCreator;
+
+      variableCreator.Name = "Initialize Evaluated Solutions";
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue()));
+      variableCreator.Successor = resultsCollector;
+
+      resultsCollector.CollectedValues.Add(new LookupParameter<IntValue>("Evaluated Solutions", null, "EvaluatedSolutions"));
+      resultsCollector.ResultsParameter.ActualName = "Results";
+      resultsCollector.Successor = mainLoop;
+
+      mainLoop.LocalImprovementParameter.ActualName = LocalImprovementParameter.Name;
+      mainLoop.ShakingParameter.ActualName = ShakingParameter.Name;
+      mainLoop.EvaluatorParameter.ActualName = EvaluatorParameter.Name;
+      mainLoop.MaximumIterationsParameter.ActualName = MaximumIterationsParameter.Name;
+      mainLoop.RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+      mainLoop.ResultsParameter.ActualName = "Results";
+      mainLoop.AnalyzerParameter.ActualName = AnalyzerParameter.Name;
+      mainLoop.EvaluatedSolutionsParameter.ActualName = "EvaluatedSolutions";
+
+      /*Initialize();*/
+    }
+  }
+}
Index: /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs
===================================================================
--- /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 5603)
+++ /branches/VNS/HeuristicLab.Algorithms.VariableNeighborhoodSearch/3.3/VariableNeighborhoodSearchMainLoop.cs	(revision 5603)
@@ -0,0 +1,278 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.Algorithms.VariableNeighborhoodSearch {
+  /// <summary>
+  /// An operator which represents a variable neighborhood search.
+  /// </summary>
+  [Item("VariableNeighborhoodSearchMainLoop", "An operator which represents the main loop of a variable neighborhood search.")]
+  [StorableClass]
+  public sealed class VariableNeighborhoodSearchMainLoop : AlgorithmOperator {
+    #region Parameter properties
+    public ValueLookupParameter<IRandom> RandomParameter {
+      get { return (ValueLookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public LookupParameter<DoubleValue> QualityParameter {
+      get { return (LookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<DoubleValue> BestKnownQualityParameter {
+      get { return (ValueLookupParameter<DoubleValue>)Parameters["BestKnownQuality"]; }
+    }
+    public ValueLookupParameter<IOperator> EvaluatorParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Evaluator"]; }
+    }
+    public ValueLookupParameter<IntValue> MaximumIterationsParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["MaximumIterations"]; }
+    }
+    public ValueLookupParameter<VariableCollection> ResultsParameter {
+      get { return (ValueLookupParameter<VariableCollection>)Parameters["Results"]; }
+    }
+    public ValueLookupParameter<IOperator> AnalyzerParameter {
+      get { return (ValueLookupParameter<IOperator>)Parameters["Analyzer"]; }
+    }
+    public LookupParameter<IntValue> EvaluatedSolutionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["EvaluatedSolutions"]; }
+    }
+    public ValueLookupParameter<ILocalImprovement> LocalImprovementParameter {
+      get { return (ValueLookupParameter<ILocalImprovement>)Parameters["LocalImprovement"]; }
+    }
+    public ValueLookupParameter<ShakingOperator> ShakingParameter {
+      get { return (ValueLookupParameter<ShakingOperator>)Parameters["Shaking"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    private VariableNeighborhoodSearchMainLoop(bool deserializing) : base(deserializing) { }
+    public VariableNeighborhoodSearchMainLoop()
+      : base() {
+        Initialize();
+    }
+    private VariableNeighborhoodSearchMainLoop(VariableNeighborhoodSearchMainLoop original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableNeighborhoodSearchMainLoop(this, cloner);
+    }
+
+    private void Initialize() {
+      #region Create parameters
+      Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>("BestKnownQuality", "The best known quality value found so far."));
+      Parameters.Add(new ValueLookupParameter<IOperator>("Evaluator", "The operator used to evaluate solutions. This operator is executed in parallel, if an engine is used which supports parallelization."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaximumIterations", "The maximum number of generations which should be processed."));
+      Parameters.Add(new ValueLookupParameter<VariableCollection>("Results", "The variable collection where results should be stored."));
+
+      Parameters.Add(new ValueLookupParameter<IOperator>("Analyzer", "The operator used to analyze the solution."));
+      Parameters.Add(new LookupParameter<IntValue>("EvaluatedSolutions", "The number of evaluated solutions."));
+      Parameters.Add(new ValueLookupParameter<ILocalImprovement>("LocalImprovement", "The local improvement operation."));
+      Parameters.Add(new ValueLookupParameter<ShakingOperator>("Shaking", "The shaking operation."));
+      #endregion
+
+      #region Create operators
+      VariableCreator variableCreator = new VariableCreator();
+      SubScopesProcessor subScopesProcessor0 = new SubScopesProcessor();
+      Assigner bestQualityInitializer = new Assigner();
+      Placeholder analyzer1 = new Placeholder();
+      ResultsCollector resultsCollector1 = new ResultsCollector();
+
+      CombinedOperator iteration = new CombinedOperator();
+      Assigner iterationInit = new Assigner();
+
+      ChildrenCreator createChild = new ChildrenCreator();
+      SubScopesProcessor childProcessor = new SubScopesProcessor();
+      ParentCopyCrossover parentCloner = new ParentCopyCrossover();
+
+      Assigner qualityAssigner = new Assigner();
+      Placeholder shaking = new Placeholder();
+      Placeholder localImprovement = new Placeholder();
+      Placeholder evaluator = new Placeholder();
+
+      QualityComparator qualityComparator = new QualityComparator();
+      ConditionalBranch improvesQualityBranch = new ConditionalBranch();
+
+      Assigner bestQualityUpdater = new Assigner();
+      ScopeCleaner cleaner = new ScopeCleaner();
+      ParentCopyCrossover originalRestorer = new ParentCopyCrossover();
+
+      IntCounter indexCounter = new IntCounter();
+      Assigner indexResetter = new Assigner();
+
+      SubScopesRemover remover = new SubScopesRemover();
+      Placeholder analyzer2 = new Placeholder();
+
+      ConditionalBranch indexTermination = new ConditionalBranch();
+
+      IntCounter iterationsCounter = new IntCounter();
+      Comparator iterationsComparator = new Comparator();
+      ConditionalBranch iterationsTermination = new ConditionalBranch();
+
+      variableCreator.CollectedValues.Add(new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("Index", new DoubleValue(0)));
+      variableCreator.CollectedValues.Add(new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(0)));
+
+      bestQualityInitializer.Name = "Initialize BestQuality";
+      bestQualityInitializer.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityInitializer.RightSideParameter.ActualName = QualityParameter.Name;
+
+      analyzer1.Name = "Analyzer (placeholder)";
+      analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+      resultsCollector1.CopyValue = new BoolValue(false);
+      resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Iterations"));
+      resultsCollector1.CollectedValues.Add(new LookupParameter<DoubleValue>("Best Quality", null, "BestQuality"));
+      resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
+
+      iteration.Name = "Iteration";
+
+      iterationInit.Name = "Init iteration";
+      iterationInit.LeftSideParameter.ActualName = "Index";
+      iterationInit.RightSideParameter.Value = new IntValue(0);
+
+      createChild.Name = "Create child";
+      createChild.ParentsPerChild.Value = 1;
+
+      parentCloner.Name = "Copy parent";
+
+      qualityAssigner.Name = "Assign quality";
+      qualityAssigner.LeftSideParameter.ActualName = "OriginalQuality";
+      qualityAssigner.RightSideParameter.ActualName = QualityParameter.Name;
+
+      shaking.Name = "Shaking operator (placeholder)";
+      shaking.OperatorParameter.ActualName = ShakingParameter.Name;
+
+      localImprovement.Name = "Local improvement operator (placeholder)";
+      localImprovement.OperatorParameter.ActualName = LocalImprovementParameter.Name;
+
+      evaluator.Name = "Evaluation operator (placeholder)";
+      evaluator.OperatorParameter.ActualName = EvaluatorParameter.Name;
+
+      qualityComparator.LeftSideParameter.ActualName = "OriginalQuality";
+      qualityComparator.RightSideParameter.ActualName = QualityParameter.Name;
+      qualityComparator.ResultParameter.ActualName = "IsBetter";
+
+      improvesQualityBranch.ConditionParameter.ActualName = "IsBetter";
+
+      bestQualityUpdater.Name = "Update BestQuality";
+      bestQualityUpdater.LeftSideParameter.ActualName = "BestQuality";
+      bestQualityUpdater.RightSideParameter.ActualName = QualityParameter.Name;
+
+      cleaner.Name = "Clean scope";
+      originalRestorer.Name = "Restore original solution";
+
+      indexCounter.Name = "Count index";
+      indexCounter.Increment.Value = 1;
+      indexCounter.ValueParameter.ActualName = "Index";
+
+      indexResetter.Name = "Reset index";
+      indexResetter.LeftSideParameter.ActualName = "Index";
+      indexResetter.RightSideParameter.Value = new IntValue(0);
+
+      remover.Name = "Remove subscope";
+
+      analyzer2.Name = "Analyzer (placeholder)";
+      analyzer2.OperatorParameter.ActualName = AnalyzerParameter.Name;
+
+      originalRestorer.Name = "Restore parent";
+
+      iterationsCounter.Name = "Iterations Counter";
+      iterationsCounter.Increment = new IntValue(1);
+      iterationsCounter.ValueParameter.ActualName = "Iterations";
+
+      iterationsComparator.Name = "Iterations >= MaximumIterations";
+      iterationsComparator.Comparison = new Comparison(ComparisonType.GreaterOrEqual);
+      iterationsComparator.LeftSideParameter.ActualName = "Iterations";
+      iterationsComparator.RightSideParameter.ActualName = MaximumIterationsParameter.Name;
+      iterationsComparator.ResultParameter.ActualName = "Terminate";
+
+      iterationsTermination.Name = "Iterations Termination Condition";
+      iterationsTermination.ConditionParameter.ActualName = "Terminate";
+
+      indexTermination.Name = "Index Termination Condition";
+      indexTermination.ConditionParameter.ActualName = "Continue";
+      #endregion
+
+      #region Create operator graph
+      OperatorGraph.InitialOperator = variableCreator;
+      variableCreator.Successor = subScopesProcessor0;
+      subScopesProcessor0.Operators.Add(bestQualityInitializer);
+      subScopesProcessor0.Successor = resultsCollector1;
+      //////////
+      bestQualityInitializer.Successor = analyzer1;
+      /////////
+      resultsCollector1.Successor = iteration;
+      iteration.OperatorGraph.InitialOperator = iterationInit;
+      iteration.Successor = iterationsCounter;
+      iterationInit.Successor = createChild;
+
+      createChild.Successor = childProcessor;
+      childProcessor.Operators.Add(parentCloner);
+      childProcessor.Successor = indexTermination;
+      /////////
+      parentCloner.Successor = qualityAssigner;
+      qualityAssigner.Successor = shaking;
+      shaking.Successor = localImprovement;
+      localImprovement.Successor = evaluator;
+      evaluator.Successor = qualityComparator;
+      qualityComparator.Successor = improvesQualityBranch;
+      improvesQualityBranch.TrueBranch = bestQualityUpdater;
+      improvesQualityBranch.FalseBranch = cleaner;
+      improvesQualityBranch.Successor = remover;
+
+      bestQualityUpdater.Successor = indexResetter;
+
+      cleaner.Successor = originalRestorer;
+      originalRestorer.Successor = indexCounter;
+      /////////
+      indexTermination.TrueBranch = null;
+      indexTermination.FalseBranch = iterationInit;
+
+      iterationsCounter.Successor = iterationsComparator;
+      iterationsComparator.Successor = iterationsTermination;
+      iterationsTermination.TrueBranch = null;
+      iterationsTermination.FalseBranch = iteration;
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      if (LocalImprovementParameter.ActualValue == null || EvaluatorParameter.ActualValue == null)
+        return null;
+      return base.Apply();
+    }
+  }
+}
