Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting.Views/3.3/VRPSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting.Views/3.3/VRPSolutionView.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting.Views/3.3/VRPSolutionView.cs	(revision 4174)
@@ -138,14 +138,14 @@
                 foreach (Tour tour in Content.Solution.Tours) {
                   double t = 0.0;
-                  Point[] tourPoints = new Point[tour.Count + 2];
+                  Point[] tourPoints = new Point[tour.Cities.Count + 2];
                   int lastCustomer = 0;
 
-                  for (int i = -1; i <= tour.Count; i++) {
+                  for (int i = -1; i <= tour.Cities.Count; i++) {
                     int location = 0;
 
-                    if (i == -1 || i == tour.Count)
+                    if (i == -1 || i == tour.Cities.Count)
                       location = 0; //depot
                     else
-                      location = tour[i].Value;
+                      location = tour.Cities[i];
 
                     Point locationPoint = new Point(border + ((int)((coordinates[location, 0] - xMin) * xStep)),
@@ -153,5 +153,5 @@
                     tourPoints[i + 1] = locationPoint;
 
-                    if (i != -1 && i != tour.Count) {
+                    if (i != -1 && i != tour.Cities.Count) {
                       Brush customerBrush = Brushes.Black;
 
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Alba/AlbaEncoding.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Alba/AlbaEncoding.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Alba/AlbaEncoding.cs	(revision 4174)
@@ -42,5 +42,5 @@
         for (int i = 0; i < this.array.Length; i++) {
           if (this.array[i] >= cities) {
-            if (tour.Count > 0) {
+            if (tour.Cities.Count > 0) {
               result.Add(tour);
 
@@ -48,9 +48,9 @@
             }
           } else {
-            tour.Add(new IntValue(this.array[i] + 1));
+            tour.Cities.Add(this.array[i] + 1);
           }
         }
 
-        if (tour.Count > 0) {
+        if (tour.Cities.Count > 0) {
           result.Add(tour);
         }
@@ -97,5 +97,5 @@
       int cities = 0;
       foreach (Tour tour in tours) {
-        cities += tour.Count;
+        cities += tour.Cities.Count;
       }
 
@@ -107,6 +107,6 @@
 
       foreach (Tour tour in tours) {
-        foreach (IntValue city in tour) {
-            array[arrayIndex] = city.Value - 1;
+        foreach (int city in tour.Cities) {
+            array[arrayIndex] = city - 1;
             arrayIndex++;
         }
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs	(revision 4174)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinCrossover.cs	(revision 4174)
@@ -0,0 +1,126 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [StorableClass]
+  public abstract class PotvinCrossover : VRPCrossover, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public PotvinCrossover() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+    }
+
+    protected abstract PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2);
+
+    protected bool FindInsertionPlace(PotvinEncoding individual, int city, out int route, out int place) {
+      return individual.FindInsertionPlace(
+        DueTimeParameter.ActualValue, ServiceTimeParameter.ActualValue, ReadyTimeParameter.ActualValue,
+        DemandParameter.ActualValue, CapacityParameter.ActualValue, CoordinatesParameter.ActualValue,
+        DistanceMatrixParameter, UseDistanceMatrixParameter.ActualValue,
+        city, -1, out route, out place);
+    }
+
+    protected bool Repair(IRandom random, PotvinEncoding solution, Tour newTour) {
+      bool success = true;
+      
+      //remove duplicates from new tour      
+      for (int i = 0; i < newTour.Cities.Count; i++) {
+        for (int j = 0; j < newTour.Cities.Count; j++) {
+          if (newTour.Cities[i] == newTour.Cities[j] && i != j) {
+            if (random.NextDouble() < 0.5)
+              newTour.Cities[i] = 0;
+            else
+              newTour.Cities[j] = 0;
+          }
+        }
+      }
+      while(newTour.Cities.Contains(0))
+        newTour.Cities.Remove(0);
+
+      //remove duplicates from old tours
+      for (int i = 0; i < newTour.Cities.Count; i++) {
+        foreach (Tour tour in solution.Tours) {
+          if (tour != newTour && tour.Cities.Contains(newTour.Cities[i])) {
+            tour.Cities.Remove(newTour.Cities[i]);
+          }
+        }
+      }
+
+      //remove empty tours
+      List<Tour> toBeDeleted = new List<Tour>();
+      foreach (Tour tour in solution.Tours) {
+        if (tour.Cities.Count == 0)
+          toBeDeleted.Add(tour);
+      }
+      foreach (Tour tour in toBeDeleted) {
+        solution.Tours.Remove(tour);
+      }
+
+      //route unrouted vehicles
+      int index = 0;
+      while (index < solution.Unrouted.Count && success) {
+        int unrouted = solution.Unrouted[index];
+
+        int route, place;
+        if(FindInsertionPlace(solution, unrouted, out route, out place)) {
+          solution.Tours[route].Cities.Insert(place, unrouted);
+        } else {
+          success = false;
+        }
+
+        index++;
+      }
+
+      for (int i = 0; i < index; i++)
+        solution.Unrouted.RemoveAt(0);
+
+      return success;
+    }
+
+    public override IOperation Apply() {
+      ItemArray<IVRPEncoding> parents = new ItemArray<IVRPEncoding>(ParentsParameter.ActualValue.Length);
+      for (int i = 0; i < ParentsParameter.ActualValue.Length; i++) {
+        IVRPEncoding solution = ParentsParameter.ActualValue[i];
+
+        if (!(solution is PotvinEncoding)) {
+          parents[i] = PotvinEncoding.ConvertFrom(solution);
+        } else {
+          parents[i] = solution;
+        }
+      }
+      ParentsParameter.ActualValue = parents;
+
+      ChildParameter.ActualValue = Crossover(RandomParameter.ActualValue, parents[0] as PotvinEncoding, parents[1] as PotvinEncoding);
+
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinSBXCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinSBXCrossover.cs	(revision 4174)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Crossovers/PotvinSBXCrossover.cs	(revision 4174)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("PotvinSBXCrossover", "The SBX crossover for the Potvin VRP representations.")]
+  [StorableClass]
+  public sealed class PotvinSBXCrossover : PotvinCrossover {
+    private Tour FindRoute(PotvinEncoding solution, int city) {
+      Tour found = null;
+
+      foreach (Tour tour in solution.Tours) {
+        if (tour.Cities.Contains(city)) {
+          found = tour;
+          break;
+        }
+      }
+
+      return found;
+    }
+    
+    protected override PotvinEncoding Crossover(IRandom random, PotvinEncoding parent1, PotvinEncoding parent2) {
+      PotvinEncoding child = parent1.Clone() as PotvinEncoding;
+      Tour newTour = new Tour();
+
+      int breakPoint1 = random.Next(1, Cities + 1);
+      Tour tour1 = FindRoute(child, breakPoint1);
+      breakPoint1 = tour1.Cities.IndexOf(breakPoint1);
+
+      for (int i = 0; i < breakPoint1; i++)
+        newTour.Cities.Add(tour1.Cities[i]);
+
+      int breakPoint2 = random.Next(1, Cities + 1);
+      Tour tour2 = FindRoute(parent2, breakPoint2);
+      breakPoint2 = tour2.Cities.IndexOf(breakPoint2);
+
+      for (int i = breakPoint2; i < tour2.Cities.Count; i++)
+        newTour.Cities.Add(tour2.Cities[i]);
+
+      child.Tours.Remove(tour1);
+      child.Tours.Add(newTour);
+
+      foreach (int city in tour1.Cities)
+        if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+          child.Unrouted.Add(city);
+
+      foreach (int city in tour2.Cities)
+        if (FindRoute(child, city) == null && !child.Unrouted.Contains(city))
+          child.Unrouted.Add(city);
+
+      if(Repair(random, child, newTour)) 
+        return child;
+      else
+        return parent1.Clone() as PotvinEncoding;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin1MManipulator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin1MManipulator.cs	(revision 4174)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin1MManipulator.cs	(revision 4174)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("Potvin1MMainpulator", "The one-level exchange operator which manipulates a Potvin VRP representation.")]
+  [StorableClass]
+  public sealed class Potvin1MMainpulator : PotvinManipulator {
+    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
+      int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
+      Tour route1 =
+        individual.Tours[selectedIndex];
+
+      List<int> replaced = new List<int>();
+      for (int i = 0; i < route1.Cities.Count; i++) {
+        int insertedRoute, insertedPlace;
+
+        if (FindInsertionPlace(individual, route1.Cities[i], selectedIndex, out insertedRoute, out insertedPlace)) {
+          individual.Tours[insertedRoute].Cities.Insert(insertedPlace, route1.Cities[i]);
+          replaced.Add(route1.Cities[i]);
+        }
+      }
+
+      route1.Cities.RemoveAll(
+        new System.Predicate<int>( 
+          delegate(int val) {
+            return (replaced.Contains(val)); 
+          }
+        )
+      );
+
+      if (route1.Cities.Count == 0)
+        individual.Tours.Remove(route1);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin2MManipulator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin2MManipulator.cs	(revision 4174)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/Potvin2MManipulator.cs	(revision 4174)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [Item("Potvin2MMainpulator", "The two-level exchange operator which manipulates a Potvin VRP representation.")]
+  [StorableClass]
+  public sealed class Potvin2MMainpulator : PotvinManipulator {
+    protected override void Manipulate(IRandom random, PotvinEncoding individual) {
+      int selectedIndex = SelectRandomTourBiasedByLength(random, individual);
+      Tour route1 =
+        individual.Tours[selectedIndex];
+
+      for (int customer1Position = 0; customer1Position < route1.Cities.Count; customer1Position++) {
+        foreach (Tour tour in individual.Tours) {
+          if (tour != route1) {
+            for (int customer2Position = 0; customer2Position < tour.Cities.Count; customer2Position++) {
+              int customer1 = route1.Cities[customer1Position];
+              int customer2 = tour.Cities[customer2Position];
+
+              //customer1 can be feasibly inserted at the location of customer2
+              tour.Cities[customer2Position] = customer1;
+              if (Feasible(tour)) {
+                int route, place;
+                if (FindInsertionPlace(individual,
+                  customer2, selectedIndex, out route, out place)) {
+                    individual.Tours[route].Cities.Insert(place, customer2);
+                  route1.Cities.RemoveAt(customer1Position);
+
+                  if (route1.Cities.Count == 0)
+                    individual.Tours.Remove(route1);
+
+                  //two-level exchange has been performed
+                  return;
+                } else {
+                  tour.Cities[customer2Position] = customer2;
+                }
+              } else {
+                tour.Cities[customer2Position] = customer2;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/PotvinManipulator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/PotvinManipulator.cs	(revision 4174)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/Manipulators/PotvinManipulator.cs	(revision 4174)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Core;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.VehicleRouting.Encodings.Potvin {
+  [StorableClass]
+  public abstract class PotvinManipulator : VRPManipulator, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public PotvinManipulator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic manipulation operators."));
+    }
+
+    protected abstract void Manipulate(IRandom random, PotvinEncoding individual);
+
+    protected int SelectRandomTourBiasedByLength(IRandom random, PotvinEncoding individual) {
+      int tourIndex = -1;
+
+      double sum = 0.0;
+      double[] probabilities = new double[individual.Tours.Count];
+      for (int i = 0; i < individual.Tours.Count; i++) {
+        probabilities[i] = 1.0 / ((double)individual.Tours[i].Cities.Count / (double)Cities);
+        sum += probabilities[i];
+      }
+
+      for (int i = 0; i < probabilities.Length; i++)
+        probabilities[i] = probabilities[i] / sum;
+
+      double rand = random.NextDouble();
+      double cumulatedProbabilities = 0.0;
+      int index = 0;
+      while (tourIndex == -1 && index < probabilities.Length) {
+        if (cumulatedProbabilities <= rand && rand <= cumulatedProbabilities + probabilities[index])
+          tourIndex = index;
+
+        cumulatedProbabilities += probabilities[index];
+        index++;
+      }
+
+      return tourIndex;
+    }
+
+    protected bool FindInsertionPlace(PotvinEncoding individual, int city, int routeToAvoid, out int route, out int place) {
+      return individual.FindInsertionPlace(
+        DueTimeParameter.ActualValue, ServiceTimeParameter.ActualValue, ReadyTimeParameter.ActualValue, 
+        DemandParameter.ActualValue, CapacityParameter.ActualValue, CoordinatesParameter.ActualValue, 
+        DistanceMatrixParameter, UseDistanceMatrixParameter.ActualValue,
+        city, routeToAvoid, out route, out place);
+    }
+    
+    public override IOperation Apply() {
+      IVRPEncoding solution = VRPSolutionParameter.ActualValue;
+      if (!(solution is PotvinEncoding)) {
+        VRPSolutionParameter.ActualValue = PotvinEncoding.ConvertFrom(solution);
+      }
+      
+      Manipulate(RandomParameter.ActualValue, VRPSolutionParameter.ActualValue as PotvinEncoding);
+
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/PotvinEncoding.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/PotvinEncoding.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Potvin/PotvinEncoding.cs	(revision 4174)
@@ -31,5 +31,5 @@
   [Item("PotvinEncoding", "Represents a potvin encoding of VRP solutions.")]
   [StorableClass]
-  class PotvinEncoding : Item, IVRPEncoding {
+  public class PotvinEncoding : Item, IVRPEncoding {
     public override Image ItemImage {
       get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Class; }
@@ -46,5 +46,5 @@
 
         foreach (Tour tour in Tours) {
-          cities += tour.Count;
+          cities += tour.Cities.Count;
         }
 
@@ -55,5 +55,5 @@
 
     [Storable]
-    public ItemList<IntValue> Unrouted { get; set; }
+    public List<int> Unrouted { get; set; }
 
     public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
@@ -61,5 +61,5 @@
       cloner.RegisterClonedObject(this, clone);
       clone.Tours = (ItemList<Tour>)cloner.Clone(this.Tours);
-      clone.Unrouted = (ItemList<IntValue>)cloner.Clone(this.Unrouted);
+      clone.Unrouted = new List<int>(Unrouted);
       return clone;
     }
@@ -67,5 +67,5 @@
     public PotvinEncoding() {
       Tours = new ItemList<Tour>();
-      Unrouted = new ItemList<IntValue>();
+      Unrouted = new List<int>();
     }
     
@@ -85,10 +85,10 @@
       for (int i = 0; i < route.Count; i++) {
         if (route[i] == 0) {
-          if (tour.Count > 0) {
+          if (tour.Cities.Count > 0) {
             solution.Tours.Add(tour);
             tour = new Tour();
           }
         } else {
-          tour.Add(new IntValue(route[i]));
+          tour.Cities.Add(route[i]);
         }
       }
@@ -96,4 +96,41 @@
       return solution;
     }
+
+    public bool FindInsertionPlace(
+      DoubleArray dueTimeArray,
+      DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
+      DoubleMatrix coordinates, ILookupParameter<DoubleMatrix> distanceMatrix, BoolValue useDistanceMatrix,
+      int city, int routeToAvoid, out int route, out int place) {
+      route = -1;
+      place = -1;
+      double minDetour = 0;
+
+      for (int tour = 0; tour < Tours.Count; tour++) {
+        if (tour != routeToAvoid) {
+          for (int i = 0; i <= Tours[tour].Cities.Count; i++) {
+            double length = Tours[tour].GetLength(coordinates, distanceMatrix, useDistanceMatrix);
+
+            Tours[tour].Cities.Insert(i, city);
+
+            if (Tours[tour].Feasible(dueTimeArray, serviceTimeArray, readyTimeArray, demandArray, 
+              capacity, coordinates, distanceMatrix, useDistanceMatrix)) {
+              double newLength = Tours[tour].GetLength(coordinates, distanceMatrix, useDistanceMatrix);
+
+              double detour = newLength - length;
+
+              if (route <= 0 || detour < minDetour) {
+                route = tour;
+                place = i;
+                minDetour = detour;
+              }
+            }
+
+            Tours[tour].Cities.RemoveAt(i);
+          }
+        }
+      }
+
+      return route >= 0 && place >= 0;
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Tour.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Tour.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Encodings/Tour.cs	(revision 4174)
@@ -22,7 +22,67 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using System.Collections.Generic;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.VehicleRouting.Encodings {
-  public class Tour : ItemList<IntValue> {
+  [StorableClass]
+  public class Tour : Item {
+    [Storable]
+    public List<int> Cities { get; private set; }
+
+    public Tour() {
+      Cities = new List<int>();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      Tour clone = base.Clone(cloner) as Tour;
+      clone.Cities = new List<int>(Cities);
+
+      return clone;
+    }
+
+    public bool Feasible(DoubleArray dueTimeArray,
+      DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
+      DoubleMatrix coordinates, ILookupParameter<DoubleMatrix> distanceMatrix, BoolValue useDistanceMatrix) {
+      TourEvaluation eval = VRPEvaluator.EvaluateTour(this,
+        dueTimeArray,
+        serviceTimeArray,
+        readyTimeArray,
+        demandArray,
+        capacity,
+        new DoubleValue(0),
+        new DoubleValue(0),
+        new DoubleValue(0),
+        new DoubleValue(1),
+        new DoubleValue(1),
+        coordinates,
+        distanceMatrix,
+        useDistanceMatrix);
+
+      return eval.Overload < double.Epsilon && eval.Tardiness < double.Epsilon;
+    }
+    
+    public double GetLength(DoubleMatrix coordinates, 
+      ILookupParameter<DoubleMatrix> distanceMatrix, 
+      BoolValue useDistanceMatrix) {
+      double length = 0;
+
+      if (Cities.Count > 0) {
+        List<int> cities = new List<int>();
+        cities.Add(0);
+        foreach (int city in Cities) {
+          cities.Add(city);
+        }
+        cities.Add(0);
+
+        for (int i = 1; i < cities.Count; i++) {
+          length += VRPUtilities.GetDistance(
+            cities[i - 1], cities[i], coordinates, distanceMatrix, useDistanceMatrix); 
+        }
+      }
+
+      return length;
+    }
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Evaluators/VRPEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Evaluators/VRPEvaluator.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/Evaluators/VRPEvaluator.cs	(revision 4174)
@@ -104,5 +104,5 @@
     }
 
-    private static TourEvaluation EvaluateTour(Tour tour, DoubleArray dueTimeArray,
+    internal static TourEvaluation EvaluateTour(Tour tour, DoubleArray dueTimeArray,
       DoubleArray serviceTimeArray, DoubleArray readyTimeArray, DoubleArray demandArray, DoubleValue capacity,
       DoubleValue fleetUsageFactor, DoubleValue timeFactor, DoubleValue distanceFactor, DoubleValue overloadPenalty, DoubleValue tardinessPenalty,
@@ -122,11 +122,11 @@
 
       //simulate a tour, start and end at depot
-      for (int i = 0; i <= tour.Count; i++) {
+      for (int i = 0; i <= tour.Cities.Count; i++) {
         int start = 0;
         if(i > 0)
-          start = tour[i - 1].Value;
+          start = tour.Cities[i - 1];
         int end = 0;
-        if(i < tour.Count)
-          end = tour[i].Value;
+        if (i < tour.Cities.Count)
+          end = tour.Cities[i];
 
         //drive there
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/HeuristicLab.Problems.VehicleRouting-3.3.csproj	(revision 4174)
@@ -107,4 +107,9 @@
   <ItemGroup>
     <Compile Include="Analyzers\BestVRPSolutionAnalyzer.cs" />
+    <Compile Include="Encodings\Potvin\Crossovers\PotvinSBXCrossover.cs" />
+    <Compile Include="Encodings\Potvin\Crossovers\PotvinCrossover.cs" />
+    <Compile Include="Encodings\Potvin\Manipulators\Potvin2MManipulator.cs" />
+    <Compile Include="Encodings\Potvin\Manipulators\Potvin1MManipulator.cs" />
+    <Compile Include="Encodings\Potvin\Manipulators\PotvinManipulator.cs" />
     <Compile Include="VRPUtilities.cs" />
     <Compile Include="VRPOperator.cs" />
@@ -222,8 +227,5 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Encodings\Potvin\Crossovers\" />
-    <Folder Include="Encodings\Potvin\Manipulators\" />
-  </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs	(revision 4173)
+++ /trunk/sources/HeuristicLab.Problems.VehicleRouting/3.3/VRPOperator.cs	(revision 4174)
@@ -24,4 +24,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Data;
+using HeuristicLab.Problems.VehicleRouting.Encodings;
 
 namespace HeuristicLab.Problems.VehicleRouting {
@@ -71,4 +72,23 @@
       Parameters.Add(new LookupParameter<DoubleArray>("ServiceTime", "The service time of each customer."));
     }
+
+    protected bool Feasible(Tour tour) {
+      return tour.Feasible(
+                  DueTimeParameter.ActualValue,
+                  ServiceTimeParameter.ActualValue,
+                  ReadyTimeParameter.ActualValue,
+                  DemandParameter.ActualValue,
+                  CapacityParameter.ActualValue,
+                  CoordinatesParameter.ActualValue,
+                  DistanceMatrixParameter,
+                  UseDistanceMatrixParameter.ActualValue);
+    }
+
+    protected double GetLength(Tour tour) {
+      return tour.GetLength(
+                CoordinatesParameter.ActualValue,
+                DistanceMatrixParameter,
+                UseDistanceMatrixParameter.ActualValue);
+    }
   }
 }
