Index: trunk/sources/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinPairwiseTwoLevelExchangeManipulator.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinPairwiseTwoLevelExchangeManipulator.cs	(revision 9456)
+++ trunk/sources/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinPairwiseTwoLevelExchangeManipulator.cs	(revision 10460)
@@ -26,4 +26,5 @@
 using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
 using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
 
 namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
@@ -44,7 +45,7 @@
     }
 
-    private PotvinEncoding ReplacePair(PotvinEncoding individual, int replaced, int replacing, bool allowInfeasible) {
+    private static PotvinEncoding ReplacePair(PotvinEncoding individual, IVRPProblemInstance instance, int replaced, int replacing, bool allowInfeasible) {
       individual = individual.Clone() as PotvinEncoding;
-      IPickupAndDeliveryProblemInstance pdp = ProblemInstance as IPickupAndDeliveryProblemInstance;
+      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
 
       int replacedDest = pdp.GetPickupDeliveryLocation(replaced);
@@ -76,9 +77,9 @@
 
       replacedSourceTour.Stops[replacedSourceTour.Stops.IndexOf(replacedSource)] = replacingSource;
-      if (!allowInfeasible && !ProblemInstance.TourFeasible(replacedSourceTour, individual))
+      if (!allowInfeasible && !instance.TourFeasible(replacedSourceTour, individual))
         return null;
 
       replacedTargetTour.Stops[replacedTargetTour.Stops.IndexOf(replacedTarget)] = replacingTarget;
-      if (!allowInfeasible && !ProblemInstance.TourFeasible(replacedTargetTour, individual))
+      if (!allowInfeasible && !instance.TourFeasible(replacedTargetTour, individual))
         return null;
 
@@ -93,12 +94,12 @@
         if (tourIdx != routeToAvoid) {
           Tour tour = individual.Tours[tourIdx];
-          VRPEvaluation eval = ProblemInstance.EvaluateTour(tour, individual);
-          individual.InsertPair(tour, replacedSource, replacedTarget, ProblemInstance);
-          VRPEvaluation evalNew = ProblemInstance.EvaluateTour(tour, individual);
+          VRPEvaluation eval = instance.EvaluateTour(tour, individual);
+          individual.InsertPair(tour, replacedSource, replacedTarget, instance);
+          VRPEvaluation evalNew = instance.EvaluateTour(tour, individual);
 
           double delta = evalNew.Quality - eval.Quality;
 
           if (delta < bestQuality &&
-              (ProblemInstance.Feasible(evalNew) || allowInfeasible)) {
+              (instance.Feasible(evalNew) || allowInfeasible)) {
             bestQuality = delta;
             bestTour = tourIdx;
@@ -127,4 +128,58 @@
     }
 
+    public static PotvinEncoding ApplyManipulation(IRandom random, PotvinEncoding individual, IPickupAndDeliveryProblemInstance pdp, bool allowInfeasible) {
+      PotvinEncoding result = null;
+      
+      int selectedIndex = SelectRandomTourBiasedByLength(random, individual, pdp);
+      if (selectedIndex >= 0) {
+        bool performed = false;
+        Tour route1 = individual.Tours[selectedIndex];
+
+        if (route1.Stops.Count > 0) {
+          //randomize customer selection
+          Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random);
+          int customer1Position = 0;
+
+          while (customer1Position < route1.Stops.Count) {
+            performed = false;
+
+            int customer1 = route1.Stops[perm[customer1Position]];
+            int customer2 = -1;
+
+            for (int i = 0; i < individual.Tours.Count; i++) {
+              if (i != selectedIndex) {
+                Tour tour = individual.Tours[i];
+                for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) {
+                  customer2 = tour.Stops[customer2Position];
+
+                  if (pdp.GetPickupDeliveryLocation(customer1) != customer2) {
+                    result = ReplacePair(individual, pdp, customer2, customer1, allowInfeasible);
+                    if (result != null) {
+                      individual = result;
+
+                      route1 = individual.Tours[selectedIndex];
+                      performed = true;
+                      break;
+                    }
+                  }
+                }
+              }
+
+              if (performed) {
+                break;
+              }
+            }
+
+            if (!performed)
+              customer1Position++;
+            else
+              break;
+          }
+        }
+      }
+
+      return result;
+    }
+
     protected override void Manipulate(IRandom random, PotvinEncoding individual) {
       bool allowInfeasible = AllowInfeasibleSolutions.Value.Value;
@@ -132,52 +187,8 @@
 
       if (pdp != null) {
-        int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
-        if (selectedIndex >= 0) {
-          bool performed = false;
-          Tour route1 = individual.Tours[selectedIndex];
-
-          if (route1.Stops.Count > 0) {
-            //randomize customer selection
-            Permutation perm = new Permutation(PermutationTypes.Absolute, route1.Stops.Count, random);
-            int customer1Position = 0;
-
-            while (customer1Position < route1.Stops.Count) {
-              performed = false;
-
-              int customer1 = route1.Stops[perm[customer1Position]];
-              int customer2 = -1;
-
-              for (int i = 0; i < individual.Tours.Count; i++) {
-                if (i != selectedIndex) {
-                  Tour tour = individual.Tours[i];
-                  for (int customer2Position = 0; customer2Position < tour.Stops.Count; customer2Position++) {
-                    customer2 = tour.Stops[customer2Position];
-
-                    if (pdp.GetPickupDeliveryLocation(customer1) != customer2) {
-                      PotvinEncoding result = ReplacePair(individual, customer2, customer1, allowInfeasible);
-                      if (result != null) {
-                        VRPToursParameter.ActualValue = result;
-                        individual = result;
-
-                        route1 = individual.Tours[selectedIndex];
-                        performed = true;
-                        break;
-                      }
-                    }
-                  }
-                }
-
-                if (performed) {
-                  break;
-                }
-              }
-
-              if (!performed)
-                customer1Position++;
-              else
-                break;
-            }
-          }
-        }
+        PotvinEncoding result = ApplyManipulation(random, individual, pdp, allowInfeasible);
+        if (result != null) {
+          VRPToursParameter.ActualValue = result;
+        }        
       }
     }
