Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InsertionManipulator.cs	(revision 14967)
@@ -50,27 +50,10 @@
     /// <param name="permutation">The permutation to manipulate.</param>
     public static void Apply(IRandom random, Permutation permutation) {
-      Permutation original = (Permutation)permutation.Clone();
-      int cutIndex, insertIndex, number;
+      var cutIndex = random.Next(permutation.Length);
+      var insertIndex = random.Next(permutation.Length);
 
-      cutIndex = random.Next(original.Length);
-      insertIndex = random.Next(original.Length);
-      number = original[cutIndex];
+      if (cutIndex == insertIndex) return;
 
-      int i = 0;  // index in new permutation
-      int j = 0;  // index in old permutation
-      while (i < original.Length) {
-        if (j == cutIndex) {
-          j++;
-        }
-        if (i == insertIndex) {
-          permutation[i] = number;
-          i++;
-        }
-        if ((i < original.Length) && (j < original.Length)) {
-          permutation[i] = original[j];
-          i++;
-          j++;
-        }
-      }
+      permutation.Move(cutIndex, cutIndex, insertIndex);
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/InversionManipulator.cs	(revision 14967)
@@ -60,9 +60,5 @@
 
     public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2) {
-      for (int i = 0; i <= (breakPoint2 - breakPoint1) / 2; i++) {  // invert permutation between breakpoints
-        int temp = permutation[breakPoint1 + i];
-        permutation[breakPoint1 + i] = permutation[breakPoint2 - i];
-        permutation[breakPoint2 - i] = temp;
-      }
+      permutation.Reverse(breakPoint1, breakPoint2 - breakPoint1 + 1);
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/ScrambleManipulator.cs	(revision 14967)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -57,4 +58,10 @@
       breakPoint2 = random.Next(breakPoint1 + 1, permutation.Length);
 
+      // TODO: Use Fisher-Yates-Shuffle rather than complicated code below
+      // scrambledIndices = Enumerable.Range(0, breakPoint2 - breakPoint1 + 1).Shuffle(random).ToArray();
+      // Also, it would be more memory-efficient to change here and Apply(Permutation, int, int[]) below to interpret scrambleArray as values, not indices
+      // Don't forget the move generator
+      // BackwardsCompatibility3.3
+      #region This whole code should be replaced by above line when going for 3.4
       scrambledIndices = new int[breakPoint2 - breakPoint1 + 1];
       remainingIndices = new int[breakPoint2 - breakPoint1 + 1];
@@ -77,4 +84,5 @@
         }
       }
+      #endregion
 
       Apply(permutation, breakPoint1, scrambledIndices);
@@ -82,8 +90,5 @@
 
     public static void Apply(Permutation permutation, int startIndex, int[] scrambleArray) {
-      Permutation original = (Permutation)permutation.Clone();
-      for (int i = 0; i < scrambleArray.Length; i++) {  // scramble permutation between breakpoints
-        permutation[startIndex + i] = original[startIndex + scrambleArray[i]];
-      }
+      permutation.Replace(startIndex, scrambleArray.Select(x => permutation[startIndex + x]).ToArray());
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap2Manipulator.cs	(revision 14967)
@@ -58,7 +58,5 @@
 
     public static void Apply(Permutation permutation, int index1, int index2) {
-      int temp = permutation[index1];
-      permutation[index1] = permutation[index2];
-      permutation[index2] = temp;
+      permutation.Swap(index1, index2);
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/Swap3Manipulator.cs	(revision 14967)
@@ -57,5 +57,5 @@
     public static void Apply(IRandom random, Permutation permutation) {
       if (permutation.Length < 3) throw new ArgumentException("Swap3Manipulator: The permutation must be at least of size 3.", "permutation");
-      int index1, index2, index3, temp;
+      int index1, index2, index3;
 
       do {
@@ -65,12 +65,6 @@
       } while (index1 == index2 || index2 == index3 || index1 == index3);
 
-      // swap positions 1 and 2
-      temp = permutation[index1];
-      permutation[index1] = permutation[index2];
-      permutation[index2] = temp;
-      // swap positions 2 and 3
-      temp = permutation[index2];
-      permutation[index2] = permutation[index3];
-      permutation[index3] = temp;
+      permutation.Swap(index1, index2);
+      permutation.Swap(index2, index3);
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Manipulators/TranslocationManipulator.cs	(revision 14967)
@@ -65,24 +65,5 @@
 
     public static void Apply(Permutation permutation, int breakPoint1, int breakPoint2, int insertPoint) {
-      Permutation original = (Permutation)permutation.Clone();
-
-      int i = 0;  // index in new permutation
-      int j = 0;  // index in old permutation
-      while (i < original.Length) {
-        if (i == insertPoint) {  // copy translocated area
-          for (int k = breakPoint1; k <= breakPoint2; k++) {
-            permutation[i] = original[k];
-            i++;
-          }
-        }
-        if (j == breakPoint1) {  // skip area between breakpoints
-          j = breakPoint2 + 1;
-        }
-        if ((i < original.Length) && (j < original.Length)) {
-          permutation[i] = original[j];
-          i++;
-          j++;
-        }
-      }
+      permutation.Move(breakPoint1, breakPoint2, insertPoint);
     }
 
Index: stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs
===================================================================
--- stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 14966)
+++ stable/HeuristicLab.Encodings.PermutationEncoding/3.3/Permutation.cs	(revision 14967)
@@ -121,4 +121,38 @@
     }
 
+    public virtual void Swap(int i, int j) {
+      var h = array[i];
+      array[i] = array[j];
+      array[j] = h;
+      OnReset();
+    }
+
+    public virtual void Reverse(int startIndex, int length) {
+      Array.Reverse(array, startIndex, length);
+      if (length > 1) OnReset();
+    }
+
+    public virtual void Move(int startIndex, int endIndex, int insertIndex) {
+      if (insertIndex == startIndex) return;
+      if (insertIndex > startIndex && insertIndex <= endIndex) {
+        var start = endIndex + 1;
+        var end = endIndex + insertIndex - startIndex;
+        insertIndex = startIndex;
+        startIndex = start;
+        endIndex = end;
+      }
+      var original = (int[])array.Clone();
+      Array.Copy(original, startIndex, array, insertIndex, endIndex - startIndex + 1);
+      if (insertIndex > endIndex)
+        Array.Copy(original, endIndex + 1, array, startIndex, insertIndex - startIndex);
+      else Array.Copy(original, insertIndex, array, insertIndex + endIndex - startIndex + 1, startIndex - insertIndex);
+      OnReset();
+    }
+
+    public virtual void Replace(int startIndex, int[] replacement) {
+      Array.Copy(replacement, 0, array, startIndex, replacement.Length);
+      OnReset();
+    }
+
     public event EventHandler PermutationTypeChanged;
 
Index: stable/HeuristicLab.Tests/HeuristicLab.Encodings.PermutationEncoding-3.3/PermutationManipulationTest.cs
===================================================================
--- stable/HeuristicLab.Tests/HeuristicLab.Encodings.PermutationEncoding-3.3/PermutationManipulationTest.cs	(revision 14967)
+++ stable/HeuristicLab.Tests/HeuristicLab.Encodings.PermutationEncoding-3.3/PermutationManipulationTest.cs	(revision 14967)
@@ -0,0 +1,181 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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 Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace HeuristicLab.Encodings.PermutationEncoding.Tests {
+  [TestClass]
+  public class PermutationManipulationTest {
+    [TestMethod]
+    [TestCategory("Encodings.Permutation")]
+    [TestProperty("Time", "short")]
+    public void TestPermutationSwap() {
+      var permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Swap(0, 0);
+      Assert.IsTrue(permutation.Validate());
+      var expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Swap(0, 9);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 9, 1, 2, 3, 4, 5, 6, 7, 8, 0 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Swap(1, 3);
+      permutation.Swap(3, 5);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 3, 2, 5, 4, 1, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+    }
+
+    [TestMethod]
+    [TestCategory("Encodings.Permutation")]
+    [TestProperty("Time", "short")]
+    public void TestPermutationReverse() {
+      var permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Reverse(0, 0);
+      Assert.IsTrue(permutation.Validate());
+      var expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Reverse(9, 1);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Reverse(0, 10);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Reverse(1, 4);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 4, 3, 2, 1, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+    }
+
+    [TestMethod]
+    [TestCategory("Encodings.Permutation")]
+    [TestProperty("Time", "short")]
+    public void TestPermutationMove() {
+      var permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(0, 0, 0);
+      Assert.IsTrue(permutation.Validate());
+      var expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(0, 0, 1);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 1, 0, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(0, 2, 3);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 3, 4, 5, 0, 1, 2, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(3, 5, 0);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 3, 4, 5, 0, 1, 2, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(3, 5, 2);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 3, 4, 5, 2, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(5, 6, 8);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 7, 8, 9, 5, 6 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(5, 7, 7);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 8, 9, 5, 6, 7 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(2, 6, 5);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 7, 8, 9, 2, 3, 4, 5, 6 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Move(3, 5, 4);
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 6, 3, 4, 5, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      var exception = false;
+      try {
+        permutation.Move(0, 5, 7);
+      } catch { exception = true; }
+      Assert.IsTrue(exception);
+    }
+
+    [TestMethod]
+    [TestCategory("Encodings.Permutation")]
+    [TestProperty("Time", "short")]
+    public void TestPermutationReplace() {
+      var permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Replace(0, new int[0]);
+      Assert.IsTrue(permutation.Validate());
+      var expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Replace(3, new [] { 3 });
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Replace(5, new [] { 8, 6, 5, 7 });
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 8, 6, 5, 7, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Replace(0, new [] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 });
+      Assert.IsTrue(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+
+      permutation = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
+      permutation.Replace(3, new[] { 5, 6, 7 });
+      Assert.IsFalse(permutation.Validate());
+      expected = new Permutation(PermutationTypes.Absolute, new[] { 0, 1, 2, 5, 6, 7, 6, 7, 8, 9 });
+      Assert.IsTrue(Auxiliary.PermutationIsEqualByPosition(expected, permutation));
+    }
+  }
+}
Index: stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 14966)
+++ stable/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 14967)
@@ -524,4 +524,5 @@
     <Compile Include="HeuristicLab.Encodings.PermutationEncoding-3.3\TranslocationManipulatorTest.cs" />
     <Compile Include="HeuristicLab.Encodings.PermutationEncoding-3.3\UniformLikeCrossoverTest.cs" />
+    <Compile Include="HeuristicLab.Encodings.PermutationEncoding-3.3\PermutationManipulationTest.cs" />
     <Compile Include="HeuristicLab.Encodings.RealVectorEncoding-3.3\Auxiliary.cs" />
     <Compile Include="HeuristicLab.Encodings.RealVectorEncoding-3.3\BlendAlphaBetaCrossoverTest.cs" />
