Index: branches/histogram/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj
===================================================================
--- branches/histogram/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 5959)
+++ branches/histogram/HeuristicLab.Optimization.Operators/3.3/HeuristicLab.Optimization.Operators-3.3.csproj	(revision 6046)
@@ -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: branches/histogram/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs
===================================================================
--- branches/histogram/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 5959)
+++ branches/histogram/HeuristicLab.Optimization.Operators/3.3/QualityComparator.cs	(revision 6046)
@@ -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: branches/histogram/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs
===================================================================
--- branches/histogram/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 6046)
+++ branches/histogram/HeuristicLab.Optimization.Operators/3.3/ShakingOperator.cs	(revision 6046)
@@ -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;
+    }
+  }
+}
