Index: branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Manipulators/SwapItemManipulator.cs
===================================================================
--- branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Manipulators/SwapNManipulator.cs	(revision 12285)
+++ branches/LinearLinkage/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/Manipulators/SwapItemManipulator.cs	(revision 12286)
@@ -20,25 +20,15 @@
 #endregion
 
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Encodings.LinearLinkageEncoding {
-  [Item("Swap-n Manipulator", "")]
+  [Item("Swap Item Manipulator", "Swaps items between groups. Items may be swapped multiple times.")]
   [StorableClass]
-  public sealed class SwapNManipulator : InstrumentedOperator, ILinearLinkageManipulator, IStochasticOperator {
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
-
-    public ILookupParameter<LinearLinkage> LLEParameter {
-      get { return (ILookupParameter<LinearLinkage>)Parameters["LLE"]; }
-    }
+  public sealed class SwapItemManipulator : LinearLinkageManipulator {
 
     public IValueLookupParameter<IntValue> NParameter {
@@ -47,12 +37,10 @@
 
     [StorableConstructor]
-    private SwapNManipulator(bool deserializing) : base(deserializing) { }
-    private SwapNManipulator(SwapNManipulator original, Cloner cloner) : base(original, cloner) { }
-    public SwapNManipulator() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
-      Parameters.Add(new LookupParameter<LinearLinkage>("LLE", "The encoding vector that is to be manipulated."));
-      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of swaps to perform.", new IntValue(2)));
+    private SwapItemManipulator(bool deserializing) : base(deserializing) { }
+    private SwapItemManipulator(SwapItemManipulator original, Cloner cloner) : base(original, cloner) { }
+    public SwapItemManipulator() {
+      Parameters.Add(new ValueLookupParameter<IntValue>("N", "The number of swaps to perform.", new IntValue(1)));
     }
-    public SwapNManipulator(int n)
+    public SwapItemManipulator(int n)
       : this() {
       NParameter.Value = new IntValue(n);
@@ -60,36 +48,32 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      return new SwapNManipulator(this, cloner);
+      return new SwapItemManipulator(this, cloner);
     }
 
-    public override IOperation InstrumentedApply() {
-      var random = RandomParameter.ActualValue;
-      var vector = LLEParameter.ActualValue;
-      var N = NParameter.ActualValue.Value;
+    public static void Apply(IRandom random, LinearLinkage lle, int n) {
+      var grouping = lle.GetGroups().Select(x => x.ToList()).ToList();
+      if (grouping.Count == 1) return; // nothing can be changed
 
-      var grouping = vector.GetGroups().Select(x => x.ToList()).ToList();
-      if (grouping.Count == 1) return base.InstrumentedApply(); // nothing can be changed
-      var touched = new HashSet<int>();
       var prevGroup = random.Next(grouping.Count);
       var prevItem = random.Next(grouping[prevGroup].Count);
-      touched.Add(grouping[prevGroup][prevItem]);
-      for (var i = 0; i < N; i++) {
-        int nextGroup = -1, nextItem = -1, tries = 0;
+      for (var i = 0; i < n; i++) {
+        int nextGroup, nextItem;
         do {
-          if (tries >= 100) break;
           nextGroup = random.Next(grouping.Count);
           nextItem = random.Next(grouping[nextGroup].Count);
-          tries++;
-        } while (nextGroup == prevGroup || touched.Contains(grouping[nextGroup][nextItem]));
-        if (tries >= 100) break;
+        } while (nextGroup == prevGroup);
         var h = grouping[nextGroup][nextItem];
         grouping[nextGroup][nextItem] = grouping[prevGroup][prevItem];
         grouping[prevGroup][prevItem] = h;
-        touched.Add(h);
         prevGroup = nextGroup;
         prevItem = nextItem;
       }
-      vector.SetGroups(grouping);
-      return base.InstrumentedApply();
+
+      lle.SetGroups(grouping);
+    }
+
+    protected override void Manipulate(IRandom random, LinearLinkage lle) {
+      var N = NParameter.ActualValue.Value;
+      Apply(random, lle, N);
     }
   }
