Index: branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/HeuristicLab.Problems.VehicleRouting.Views-3.4.csproj
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/HeuristicLab.Problems.VehicleRouting.Views-3.4.csproj	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/HeuristicLab.Problems.VehicleRouting.Views-3.4.csproj	(revision 6856)
@@ -112,4 +112,10 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="MDCVRPPDTWView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MDCVRPPDTWView.Designer.cs">
+      <DependentUpon>MDCVRPPDTWView.cs</DependentUpon>
+    </Compile>
     <Compile Include="MDCVRPTWView.cs">
       <SubType>UserControl</SubType>
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.Designer.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.Designer.cs	(revision 6856)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.Designer.cs	(revision 6856)
@@ -0,0 +1,31 @@
+﻿namespace HeuristicLab.Problems.VehicleRouting.Views {
+  partial class MDCVRPPDTWView {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+    }
+
+    #endregion
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.cs	(revision 6856)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting.Views/3.4/MDCVRPPDTWView.cs	(revision 6856)
@@ -0,0 +1,205 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.VehicleRouting.Views {
+  [View("MDCVRPPDTWProblemInstance View")]
+  [Content(typeof(MDCVRPPDTWProblemInstance), true)]
+  public partial class MDCVRPPDTWView : VRPProblemInstanceView {
+    public new MDCVRPPDTWProblemInstance Content {
+      get { return (MDCVRPPDTWProblemInstance)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public MDCVRPPDTWView() {
+      InitializeComponent();
+    }
+
+    private bool drawFlow = false;
+
+    protected override void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
+      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
+        drawFlow = !drawFlow;
+        GenerateImage();
+      }      
+    }
+
+    protected override void DrawVisualization(Bitmap bitmap) {
+      DoubleMatrix coordinates = Content.Coordinates;
+      DoubleMatrix distanceMatrix = Content.DistanceMatrix;
+      BoolValue useDistanceMatrix = Content.UseDistanceMatrix;
+      DoubleArray dueTime = Content.DueTime;
+      DoubleArray serviceTime = Content.ServiceTime;
+      DoubleArray readyTime = Content.ReadyTime;
+      DoubleArray demand = Content.Demand;
+      IntArray pickupDeliveryLocation = Content.PickupDeliveryLocation;
+      IntArray vehicleAssignment = Content.VehicleDepotAssignment;
+
+      int depots = Content.Depots.Value;
+      int cities = Content.Cities.Value;
+
+      Pen[] pens = {new Pen(Color.FromArgb(92,20,237)), new Pen(Color.FromArgb(237,183,20)), new Pen(Color.FromArgb(237,20,219)), new Pen(Color.FromArgb(20,237,76)),
+                    new Pen(Color.FromArgb(237,61,20)), new Pen(Color.FromArgb(115,78,26)), new Pen(Color.FromArgb(20,237,229)), new Pen(Color.FromArgb(39,101,19)),
+                    new Pen(Color.FromArgb(230,170,229)), new Pen(Color.FromArgb(142,136,89)), new Pen(Color.FromArgb(157,217,166)), new Pen(Color.FromArgb(31,19,101)),
+                    new Pen(Color.FromArgb(173,237,20)), new Pen(Color.FromArgb(230,231,161)), new Pen(Color.FromArgb(142,89,89)), new Pen(Color.FromArgb(93,89,142)),
+                    new Pen(Color.FromArgb(146,203,217)), new Pen(Color.FromArgb(101,19,75)), new Pen(Color.FromArgb(198,20,237)), new Pen(Color.FromArgb(185,185,185)),
+                    new Pen(Color.FromArgb(179,32,32)), new Pen(Color.FromArgb(18,119,115)), new Pen(Color.FromArgb(104,158,239)), new Pen(Color.Black)};
+
+      Pen flowPen = new Pen(Brushes.Red, 3);
+      flowPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
+      flowPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
+
+      if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) {
+        double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue;
+        for (int i = 0; i < coordinates.Rows; i++) {
+          if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0];
+          if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1];
+          if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0];
+          if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1];
+        }
+
+        int border = 20;
+        double xStep = xMax != xMin ? (bitmap.Width - 2 * border) / (xMax - xMin) : 1;
+        double yStep = yMax != yMin ? (bitmap.Height - 2 * border) / (yMax - yMin) : 1;
+
+        using (Graphics graphics = Graphics.FromImage(bitmap)) {
+          if (Solution != null) {
+            for (int i = 0; i < Content.Depots.Value; i++) {
+              Point locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+              graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10);
+            }
+
+            int currentTour = 0;
+            foreach (Tour tour in Solution.GetTours()) {
+              int tourIndex = Solution.GetTourIndex(tour);
+              int vehicle = Solution.GetVehicleAssignment(tourIndex);
+              int depot = vehicleAssignment[vehicle];
+
+              double t = 0.0;
+              Point[] tourPoints = new Point[tour.Stops.Count + 2];
+              Brush[] customerBrushes = new Brush[tour.Stops.Count];
+              Pen[] customerPens = new Pen[tour.Stops.Count];
+              bool[] validPickupDelivery = new bool[tour.Stops.Count];
+              int lastCustomer = 0;
+
+              Dictionary<int, bool> stops = new Dictionary<int, bool>();
+              for (int i = -1; i <= tour.Stops.Count; i++) {
+                int location = 0;
+
+                if (i == -1 || i == tour.Stops.Count)
+                  location = 0; //depot
+                else
+                  location = tour.Stops[i];
+
+                Point locationPoint;
+                if (location == 0) {
+                  locationPoint = new Point(border + ((int)((Content.Coordinates[depot, 0] - xMin) * xStep)),
+                                  bitmap.Height - (border + ((int)((Content.Coordinates[depot, 1] - yMin) * yStep))));
+                } else {
+                  locationPoint = new Point(border + ((int)((Content.GetCoordinates(location)[0] - xMin) * xStep)),
+                                  bitmap.Height - (border + ((int)((Content.GetCoordinates(location)[1] - yMin) * yStep))));
+                }
+                tourPoints[i + 1] = locationPoint;
+
+                if (i != -1 && i != tour.Stops.Count) {
+                  Brush customerBrush = Brushes.Black;
+                  Pen customerPen = Pens.Black;
+
+                  t += Content.GetDistance(
+                    lastCustomer, location, Solution);
+
+                  int locationIndex;
+                  if (location == 0)
+                    locationIndex = depot;
+                  else
+                    locationIndex = location + depots - 1;
+
+                  if (t < readyTime[locationIndex]) {
+                    t = readyTime[locationIndex];
+                    customerBrush = Brushes.Orange;
+                    customerPen = Pens.Orange;
+
+                  } else if (t > dueTime[locationIndex]) {
+                    customerBrush = Brushes.Red;
+                    customerPen = Pens.Red;
+                  }
+
+                  t += serviceTime[location - 1];
+
+                  validPickupDelivery[i] =
+                    ((demand[location - 1] >= 0) ||
+                     (stops.ContainsKey(pickupDeliveryLocation[location - 1])));
+
+                  customerBrushes[i] = customerBrush;
+                  customerPens[i] = customerPen;
+
+                  stops.Add(location, true);
+                }
+                lastCustomer = location;
+              }
+
+              if (!drawFlow)
+                graphics.DrawPolygon(pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))], tourPoints);
+
+              for (int i = 0; i < tour.Stops.Count; i++) {
+                if (validPickupDelivery[i]) {
+                  graphics.FillRectangle(customerBrushes[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
+
+                  if (demand[tour.Stops[i] - 1] < 0 && drawFlow) {
+                    int location = pickupDeliveryLocation[tour.Stops[i] - 1];
+                    int source = tour.Stops.IndexOf(location);
+
+                    graphics.DrawLine(flowPen, tourPoints[source + 1], tourPoints[i + 1]);
+                  }
+                } else
+                  graphics.DrawRectangle(customerPens[i], tourPoints[i + 1].X - 3, tourPoints[i + 1].Y - 3, 6, 6);
+              }
+
+              graphics.FillEllipse(Brushes.DarkBlue, tourPoints[0].X - 5, tourPoints[0].Y - 5, 10, 10);
+
+              currentTour++;
+            }
+          } else {
+            {
+              Point[] locationPoints = new Point[coordinates.Rows];
+              //just draw customers
+              for (int i = 1; i < coordinates.Rows; i++) {
+                locationPoints[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+
+                graphics.FillRectangle(Brushes.Black, locationPoints[i].X - 3, locationPoints[i].Y - 3, 6, 6);
+              }
+
+              if (drawFlow) {
+                for (int i = 0; i < cities; i++) {
+                  if (demand[i] < 0) {
+                    graphics.DrawLine(flowPen, locationPoints[pickupDeliveryLocation[i]], locationPoints[i + 1]);
+                  }
+                }
+              }
+
+              for (int i = 0; i < Content.Depots.Value; i++) {
+                Point locationPoint = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)),
+                                  bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep))));
+                graphics.FillEllipse(Brushes.Blue, locationPoint.X - 5, locationPoint.Y - 5, 10, 10);
+              }
+            }
+          }
+        }
+      }
+
+      for (int i = 0; i < pens.Length; i++)
+        pens[i].Dispose();
+
+      flowPen.Dispose();
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/IterativeInsertionCreator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/IterativeInsertionCreator.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/IterativeInsertionCreator.cs	(revision 6856)
@@ -113,6 +113,6 @@
 
         if (pdp != null) {
-          stopIdx = result.FindBestInsertionPlace(currentTour, pdp.PickupDeliveryLocation[customers[index]]);
-          currentTour.Stops.Insert(stopIdx, pdp.PickupDeliveryLocation[customers[index]]);
+          stopIdx = result.FindBestInsertionPlace(currentTour, pdp.GetPickupDeliveryLocation(customers[index]));
+          currentTour.Stops.Insert(stopIdx, pdp.GetPickupDeliveryLocation(customers[index]));
         }
 
@@ -122,5 +122,5 @@
             currentTour.Stops.Remove(customers[index]);
             if (pdp != null)
-              currentTour.Stops.Remove(pdp.PickupDeliveryLocation[customers[index]]);
+              currentTour.Stops.Remove(pdp.GetPickupDeliveryLocation(customers[index]));
 
           if (currentTour.Stops.Count == 0)
@@ -131,5 +131,5 @@
           currentTour.Stops.Add(customers[index]);
           if (pdp != null) {
-            currentTour.Stops.Add(pdp.PickupDeliveryLocation[customers[index]]);
+            currentTour.Stops.Add(pdp.GetPickupDeliveryLocation(customers[index]));
           }
         }
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/PushForwardInsertionCreator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/PushForwardInsertionCreator.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/ExtendedPotvin/Creators/PushForwardInsertionCreator.cs	(revision 6856)
@@ -213,5 +213,5 @@
 
         if (pdp != null) {
-          tour.Stops.Add(pdp.PickupDeliveryLocation[unroutedList[0]]);
+          tour.Stops.Add(pdp.GetPickupDeliveryLocation(unroutedList[0]));
         }
 
@@ -234,5 +234,5 @@
                   bool feasible;
                   cost = tourCost +
-                    problemInstance.GetInsertionCosts(eval, result, pdp.PickupDeliveryLocation[unroutedList[c]], 0, j, out feasible);
+                    problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unroutedList[c]), 0, j, out feasible);
                   if (cost < minimumCost && feasible) {
                     minimumCost = cost;
@@ -260,5 +260,5 @@
             tour.Stops.Insert(indexOfMinimumCost, unroutedList[indexOfCustomer]);
             if (pdp != null) {
-              tour.Stops.Insert(indexOfMinimumCost2, pdp.PickupDeliveryLocation[unroutedList[indexOfCustomer]]);
+              tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(unroutedList[indexOfCustomer]));
             }
 
@@ -275,5 +275,5 @@
             tour.Stops.Add(unroutedList[0]);
             if (pdp != null) {
-              tour.Stops.Add(pdp.PickupDeliveryLocation[unroutedList[0]]);
+              tour.Stops.Add(pdp.GetPickupDeliveryLocation(unroutedList[0]));
             }
 
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinCustomerRelocationManipulator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinCustomerRelocationManipulator.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Manipulators/PotvinCustomerRelocationManipulator.cs	(revision 6856)
@@ -68,5 +68,5 @@
           int stop = route1.Stops[i];
           if (ProblemInstance.GetDemand(stop) < 0) {
-            int source = pdp.PickupDeliveryLocation[stop];
+            int source = pdp.GetPickupDeliveryLocation(stop);
 
             if (!visited.ContainsKey(source))
@@ -81,5 +81,5 @@
             deliveryViolations[random.Next(deliveryViolations.Count)];
 
-          int source = pdp.PickupDeliveryLocation[selected];
+          int source = pdp.GetPickupDeliveryLocation(selected);
 
           //find route of source
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeExhaustiveMoveGenerator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeExhaustiveMoveGenerator.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeExhaustiveMoveGenerator.cs	(revision 6856)
@@ -67,7 +67,7 @@
                   if (pdp == null || pdp.GetDemand(city2) >= 0) {
                     bool valid = pdp == null ||
-                      (pdp.PickupDeliveryLocation[city2] != pdp.PickupDeliveryLocation[city1] &&
-                       pdp.PickupDeliveryLocation[city2] != city1 &&
-                       pdp.PickupDeliveryLocation[city1] != city2);
+                      (pdp.GetPickupDeliveryLocation(city2) != pdp.GetPickupDeliveryLocation(city1) &&
+                       pdp.GetPickupDeliveryLocation(city2) != city1 &&
+                       pdp.GetPickupDeliveryLocation(city1) != city2);
 
                     if (valid) {
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeMoveMaker.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeMoveMaker.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeMoveMaker.cs	(revision 6856)
@@ -68,12 +68,11 @@
 
       if (problemInstance is IPickupAndDeliveryProblemInstance) {
-        IntArray pickupLocation =
-          (problemInstance as IPickupAndDeliveryProblemInstance).PickupDeliveryLocation;
+        IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
 
-        int location = pickupLocation[move.City];
+        int location = pdp.GetPickupDeliveryLocation(move.City);
         Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));
         oldTour2.Stops.Remove(location);
 
-        location = pickupLocation[move.Replaced];
+        location = pdp.GetPickupDeliveryLocation(move.Replaced);
         oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));
 
@@ -81,6 +80,6 @@
         tour.Stops.Remove(move.Replaced);
 
-        PotvinPDRearrangeMoveMaker.InsertPair(solution, tour, move.City, pickupLocation[move.City], problemInstance);
-        PotvinPDRearrangeMoveMaker.InsertPair(solution, oldTour, move.Replaced, pickupLocation[move.Replaced], problemInstance);
+        PotvinPDRearrangeMoveMaker.InsertPair(solution, tour, move.City, pdp.GetPickupDeliveryLocation(move.City), problemInstance);
+        PotvinPDRearrangeMoveMaker.InsertPair(solution, oldTour, move.Replaced, pdp.GetPickupDeliveryLocation(move.Replaced), problemInstance);
       } else {
         tour.Stops.Remove(move.Replaced);
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeSingleMoveGenerator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeSingleMoveGenerator.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDExchange/PotvinPDExchangeSingleMoveGenerator.cs	(revision 6856)
@@ -85,7 +85,7 @@
           if (pdp == null ||
             (pdp.GetDemand(stop) >= 0 &&
-             pdp.PickupDeliveryLocation[stop] != pdp.PickupDeliveryLocation[city] &&
-             pdp.PickupDeliveryLocation[stop] != city &&
-             pdp.PickupDeliveryLocation[city] != stop))
+            pdp.GetPickupDeliveryLocation(stop) != pdp.GetPickupDeliveryLocation(city) &&
+            pdp.GetPickupDeliveryLocation(stop) != city &&
+            pdp.GetPickupDeliveryLocation(city) != stop))
             tourCities.Add(stop);
         }
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDRearrange/PotvinPDRearrangeMoveMaker.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDRearrange/PotvinPDRearrangeMoveMaker.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDRearrange/PotvinPDRearrangeMoveMaker.cs	(revision 6856)
@@ -97,5 +97,5 @@
       IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
       if (pdp != null) {
-        int location = pdp.PickupDeliveryLocation[move.City];
+        int location = pdp.GetPickupDeliveryLocation(move.City);
         Tour tour2 = solution.Tours.Find(t => t.Stops.Contains(location));
         int position2 = tour2.Stops.IndexOf(location);
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDShift/PotvinPDShiftMoveMaker.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDShift/PotvinPDShiftMoveMaker.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Encodings/Potvin/Moves/PickupDelivery/PDShift/PotvinPDShiftMoveMaker.cs	(revision 6856)
@@ -68,12 +68,11 @@
 
       if (problemInstance is IPickupAndDeliveryProblemInstance) {
-        IntArray pickupLocation =
-          (problemInstance as IPickupAndDeliveryProblemInstance).PickupDeliveryLocation;
-
-        int location = pickupLocation[move.City];
+        IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
+        
+        int location = pdp.GetPickupDeliveryLocation(move.City);
         Tour oldTour2 = solution.Tours.Find(t => t.Stops.Contains(location));
         oldTour2.Stops.Remove(location);
 
-        PotvinPDRearrangeMoveMaker.InsertPair(solution, tour, move.City, pickupLocation[move.City], problemInstance);
+        PotvinPDRearrangeMoveMaker.InsertPair(solution, tour, move.City, location, problemInstance);
       } else {
         int place = solution.FindBestInsertionPlace(tour, move.City);
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/HeuristicLab.Problems.VehicleRouting-3.4.csproj	(revision 6856)
@@ -301,4 +301,6 @@
     <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPEvaluator.cs" />
     <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPProblemInstance.cs" />
+    <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPTW\MDCVRPPDTW\MDCVRPPDTWEvaluator.cs" />
+    <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPTW\MDCVRPPDTW\MDCVRPPDTWProblemInstance.cs" />
     <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPTW\MDCVRPTWEvaluator.cs" />
     <Compile Include="ProblemInstances\MultiDepotVRP\MDCVRP\MDCVRPTW\MDCVRPTWProblemInstance.cs" />
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWEvaluator.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWEvaluator.cs	(revision 6856)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWEvaluator.cs	(revision 6856)
@@ -0,0 +1,343 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.Encodings;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
+  [Item("MDCVRPPDTWEvaluator", "Represents a multi depot CVRPPDTW evaluator.")]
+  [StorableClass]
+  public class MDCVRPPDTWEvaluator: MDCVRPTWEvaluator {
+    public ILookupParameter<IntValue> PickupViolationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["PickupViolations"]; }
+    }
+
+    protected override VRPEvaluation CreateTourEvaluation() {
+      return new CVRPPDTWEvaluation();
+    }
+
+    protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) {
+      TourInsertionInfo tourInfo = new TourInsertionInfo();
+      eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
+
+      IHeterogenousCapacitatedProblemInstance cvrpInstance = instance as IHeterogenousCapacitatedProblemInstance;
+      DoubleArray demand = instance.Demand;
+
+      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
+      DoubleArray dueTime = vrptw.DueTime;
+      DoubleArray readyTime = vrptw.ReadyTime;
+      DoubleArray serviceTimes = vrptw.ServiceTime;
+
+      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
+      IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation;
+
+      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
+      IntArray vehicleAssignment = mdp.VehicleDepotAssignment;
+      int depots = mdp.Depots.Value;
+
+      double time = 0.0;
+      double waitingTime = 0.0;
+      double serviceTime = 0.0;
+      double tardiness = 0.0;
+      double overweight = 0.0;
+      double distance = 0.0;
+
+      int tourIndex = solution.GetTourIndex(tour);
+      int vehicle = solution.GetVehicleAssignment(tourIndex);
+      int depot = vehicleAssignment[vehicle];
+
+      double capacity = cvrpInstance.Capacity[vehicle];
+
+      double currentLoad = 0.0;
+      Dictionary<int, bool> stops = new Dictionary<int, bool>();
+      int pickupViolations = 0;
+
+      double tourStartTime = readyTime[0];
+      time = tourStartTime;
+
+      //simulate a tour, start and end at depot
+      for (int i = 0; i <= tour.Stops.Count; i++) {
+        int start = 0;
+        if (i > 0)
+          start = tour.Stops[i - 1];
+        int end = 0;
+        if (i < tour.Stops.Count)
+          end = tour.Stops[i];
+
+        //drive there
+        double currentDistace = vrptw.GetDistance(start, end, solution);
+        time += currentDistace;
+        distance += currentDistace;
+
+        double arrivalTime = time;
+
+        int endIndex;
+        if (end == 0)
+          endIndex = depot;
+        else
+          endIndex = end + depots - 1;
+
+        //check if it was serviced on time
+        if (time > dueTime[endIndex])
+          tardiness += time - dueTime[endIndex];
+
+        //wait
+        double currentWaitingTime = 0.0;
+        if (time < readyTime[endIndex])
+          currentWaitingTime = readyTime[endIndex] - time;
+
+        double waitTime = readyTime[endIndex] - time;
+
+        waitingTime += currentWaitingTime;
+        time += currentWaitingTime;
+
+        double spareTime = dueTime[endIndex] - time;
+        double arrivalSpareCapacity = capacity - currentLoad;
+
+        if (end > 0) {
+          //service
+          double currentServiceTime = serviceTimes[end - 1];
+          serviceTime += currentServiceTime;
+          time += currentServiceTime;
+
+          //Pickup / deliver
+          bool validPickupDelivery =
+            validPickupDelivery =
+            ((demand[end - 1] >= 0) ||
+             (stops.ContainsKey(pickupDeliveryLocation[end - 1])));
+
+          if (validPickupDelivery) {
+            currentLoad += demand[end - 1];
+          } else {
+            pickupViolations++;
+          }
+
+          if (currentLoad > capacity)
+            overweight += currentLoad - capacity;
+        }
+
+        double spareCapacity = capacity - currentLoad;
+        CVRPPDTWInsertionInfo stopInfo = new CVRPPDTWInsertionInfo(start, end, spareCapacity, tourStartTime, 
+          arrivalTime, time, spareTime, waitTime, new List<int>(stops.Keys), arrivalSpareCapacity);
+        tourInfo.AddStopInsertionInfo(stopInfo);
+
+        stops.Add(end, true);
+      }
+
+      eval.Quality += instance.FleetUsageFactor.Value;
+      eval.Quality += instance.DistanceFactor.Value * distance;
+      eval.Distance += distance;
+      eval.VehicleUtilization += 1;
+
+      (eval as CVRPEvaluation).Overload += overweight;
+      double tourPenalty = 0;
+      double penalty = overweight * cvrpInstance.OverloadPenalty.Value;
+      eval.Penalty += penalty;
+      eval.Quality += penalty;
+      tourPenalty += penalty;
+
+      (eval as CVRPTWEvaluation).Tardiness += tardiness;
+      (eval as CVRPTWEvaluation).TravelTime += time;
+
+      penalty = tardiness * vrptw.TardinessPenalty.Value;
+      eval.Penalty += penalty;
+      eval.Quality += penalty;
+      tourPenalty += penalty;
+
+      (eval as CVRPPDTWEvaluation).PickupViolations += pickupViolations;
+      penalty = pickupViolations * pdp.PickupViolationPenalty.Value;
+      eval.Penalty += penalty;
+      tourPenalty += penalty;
+
+      eval.Quality += penalty;
+      eval.Quality += time * vrptw.TimeFactor.Value;
+      tourInfo.Penalty = tourPenalty;
+    }
+
+    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, 
+      out bool feasible) {
+      CVRPPDTWInsertionInfo insertionInfo = tourInsertionInfo.GetStopInsertionInfo(index) as CVRPPDTWInsertionInfo;
+
+      double costs = 0;
+      feasible = tourInsertionInfo.Penalty < double.Epsilon;
+      bool tourFeasible = true;
+
+      ICapacitatedProblemInstance cvrp = instance as ICapacitatedProblemInstance;
+      double overloadPenalty = cvrp.OverloadPenalty.Value;
+
+      ITimeWindowedProblemInstance vrptw = instance as ITimeWindowedProblemInstance;
+      DoubleArray dueTime = vrptw.DueTime;
+      DoubleArray readyTime = vrptw.ReadyTime;
+      DoubleArray serviceTimes = vrptw.ServiceTime;
+      double tardinessPenalty = vrptw.TardinessPenalty.Value;
+
+      IMultiDepotProblemInstance mdp = instance as IMultiDepotProblemInstance;
+      int depots = mdp.Depots.Value;
+
+      IPickupAndDeliveryProblemInstance pdp = instance as IPickupAndDeliveryProblemInstance;
+      IntArray pickupDeliveryLocation = pdp.PickupDeliveryLocation;
+      double pickupPenalty = pdp.PickupViolationPenalty.Value;
+
+      double startDistance, endDistance;
+      costs += instance.GetInsertionDistance(insertionInfo.Start, customer, insertionInfo.End, solution, out startDistance, out endDistance);
+
+      double demand = instance.GetDemand(customer);
+      if (demand > insertionInfo.ArrivalSpareCapacity) {
+        tourFeasible = feasible = false;
+        if (insertionInfo.ArrivalSpareCapacity >= 0)
+          costs += (demand - insertionInfo.ArrivalSpareCapacity) * overloadPenalty;
+        else
+          costs += demand * overloadPenalty;
+      }
+      int destination = pickupDeliveryLocation[customer - 1];
+
+      bool validPickup = true;
+      if (demand < 0 && !insertionInfo.Visited.Contains(destination)) {
+        tourFeasible = feasible = false;
+        validPickup = false;
+        costs += pickupPenalty;
+      }
+
+      double time = 0;
+      double tardiness = 0;
+
+      if (index > 0)
+        time = (tourInsertionInfo.GetStopInsertionInfo(index - 1) as CVRPTWInsertionInfo).LeaveTime;
+      else
+        time = insertionInfo.TourStartTime;
+
+      time += startDistance;
+
+      int customerIndex = customer + depots - 1;
+
+      if (time > dueTime[customerIndex]) {
+        tardiness += time - dueTime[customerIndex];
+      }
+      if (time < readyTime[customerIndex])
+        time += readyTime[customerIndex] - time;
+      time += serviceTimes[customer - 1];
+      time += endDistance;
+
+      double additionalTime = time - (tourInsertionInfo.GetStopInsertionInfo(index) as CVRPTWInsertionInfo).ArrivalTime;
+      for (int i = index; i < tourInsertionInfo.GetStopCount(); i++) {
+        CVRPTWInsertionInfo nextStop = tourInsertionInfo.GetStopInsertionInfo(i) as CVRPTWInsertionInfo;
+
+        if (demand >= 0) {
+          if (nextStop.End == destination) {
+            demand = 0;
+            costs -= pickupPenalty;
+            if (tourInsertionInfo.Penalty == pickupPenalty && tourFeasible)
+              feasible = true;
+          } else if (nextStop.SpareCapacity < 0) {
+            costs += demand * overloadPenalty;
+          } else if (nextStop.SpareCapacity < demand) {
+            tourFeasible = feasible = false;
+            costs += (demand - nextStop.SpareCapacity) * overloadPenalty;
+          }
+        } else if (validPickup) {
+          if (nextStop.SpareCapacity < 0) {
+            costs += Math.Max(demand, nextStop.SpareCapacity) * overloadPenalty;
+          }
+        }
+
+        if (additionalTime < 0) {
+          //arrive earlier than before
+          //wait probably
+          if (nextStop.WaitingTime < 0) {
+            double wait = nextStop.WaitingTime - additionalTime;
+            if (wait > 0)
+              additionalTime += wait;
+          } else {
+            additionalTime = 0;
+          }
+
+          //check due date, decrease tardiness
+          if (nextStop.SpareTime < 0) {
+            costs += Math.Max(nextStop.SpareTime, additionalTime) * tardinessPenalty;
+          }
+        } else {
+          //arrive later than before, probably don't have to wait
+          if (nextStop.WaitingTime > 0) {
+            additionalTime -= Math.Min(additionalTime, nextStop.WaitingTime);
+          }
+
+          //check due date
+          if (nextStop.SpareTime > 0) {
+            double spare = nextStop.SpareTime - additionalTime;
+            if (spare < 0)
+              tardiness += -spare;
+          } else {
+            tardiness += additionalTime;
+          }
+        }
+      }
+
+      costs += additionalTime * vrptw.TimeFactor.Value;
+
+      if (tardiness > 0) {
+        tourFeasible = feasible = false;
+      }
+
+      costs += tardiness * tardinessPenalty;
+
+      return costs;
+    }
+
+    protected override void InitResultParameters() {
+      base.InitResultParameters();
+
+      PickupViolationsParameter.ActualValue = new IntValue(0);
+    }
+
+    protected override void SetResultParameters(VRPEvaluation tourEvaluation) {
+      base.SetResultParameters(tourEvaluation);
+
+      PickupViolationsParameter.ActualValue.Value = (tourEvaluation as CVRPPDTWEvaluation).PickupViolations;
+    }
+    
+    [StorableConstructor]
+    protected MDCVRPPDTWEvaluator(bool deserializing) : base(deserializing) { }
+
+    public MDCVRPPDTWEvaluator() {
+      Parameters.Add(new LookupParameter<IntValue>("PickupViolations", "The number of pickup violations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MDCVRPPDTWEvaluator(this, cloner);
+    }
+
+    protected MDCVRPPDTWEvaluator(MDCVRPPDTWEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWProblemInstance.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWProblemInstance.cs	(revision 6856)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/MultiDepotVRP/MDCVRP/MDCVRPTW/MDCVRPPDTW/MDCVRPPDTWProblemInstance.cs	(revision 6856)
@@ -0,0 +1,136 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances {
+  [Item("MDCVRPPDTWProblemInstance", "Represents a multi depot CVRPPDTW instance.")]
+  [StorableClass]
+  public class MDCVRPPDTWProblemInstance: MDCVRPTWProblemInstance, IPickupAndDeliveryProblemInstance {
+    protected IValueParameter<IntArray> PickupDeliveryLocationParameter {
+      get { return (IValueParameter<IntArray>)Parameters["PickupDeliveryLocation"]; }
+    }
+    protected IValueParameter<DoubleValue> PickupViolationPenaltyParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["EvalPickupViolationPenalty"]; }
+    }
+    
+    public IntArray PickupDeliveryLocation {
+      get { return PickupDeliveryLocationParameter.Value; }
+      set { PickupDeliveryLocationParameter.Value = value; }
+    }
+
+    [Storable]
+    private DoubleValue currentPickupViolationPenalty;
+
+    public DoubleValue PickupViolationPenalty {
+      get {
+        if (currentPickupViolationPenalty != null)
+          return currentPickupViolationPenalty;
+        else
+          return PickupViolationPenaltyParameter.Value;
+      }
+      set { currentPickupViolationPenalty = value; }
+    }
+
+    protected override IEnumerable<IOperator> GetOperators() {
+      return 
+        ApplicationManager.Manager.GetInstances<IPickupAndDeliveryOperator>()
+        .Where(o => !(o is IAnalyzer))
+        .Cast<IOperator>().Union(base.GetOperators());
+    }
+
+    protected override IEnumerable<IOperator> GetAnalyzers() {
+      return ApplicationManager.Manager.GetInstances<IPickupAndDeliveryOperator>()
+        .Where(o => o is IAnalyzer)
+        .Cast<IOperator>().Union(base.GetAnalyzers());
+    }
+    
+    protected override IVRPEvaluator Evaluator {
+      get {
+        return new MDCVRPPDTWEvaluator();
+      }
+    }
+
+    public int GetPickupDeliveryLocation(int city) {
+      return PickupDeliveryLocation[city - 1];
+    }
+    
+    [StorableConstructor]
+    protected MDCVRPPDTWProblemInstance(bool deserializing) : base(deserializing) { }
+
+    public MDCVRPPDTWProblemInstance() {
+      Parameters.Add(new ValueParameter<IntArray>("PickupDeliveryLocation", "The pickup and delivery location for each customer.", new IntArray()));
+
+      Parameters.Add(new ValueParameter<DoubleValue>("EvalPickupViolationPenalty", "The pickup violation penalty considered in the evaluation.", new DoubleValue(100)));
+
+      AttachEventHandlers();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MDCVRPPDTWProblemInstance(this, cloner);
+    }
+
+    protected MDCVRPPDTWProblemInstance(MDCVRPPDTWProblemInstance original, Cloner cloner)
+      : base(original, cloner) {
+        currentPickupViolationPenalty = cloner.Clone(original.currentPickupViolationPenalty) as DoubleValue;
+
+        AttachEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserializationHook() {
+      AttachEventHandlers();
+    }
+
+    private void AttachEventHandlers() {
+      PickupDeliveryLocationParameter.ValueChanged += new EventHandler(PickupDeliveryLocationParameter_ValueChanged);
+    }
+
+    public override void InitializeState() {
+      base.InitializeState();
+
+      currentPickupViolationPenalty = null;
+    }
+
+    #region Event handlers
+    void PickupDeliveryLocationParameter_ValueChanged(object sender, EventArgs e) {
+      PickupDeliveryLocationParameter.Value.ItemChanged += new EventHandler<EventArgs<int>>(Value_ItemChanged);
+      EvalBestKnownSolution();
+    }
+
+    void Value_ItemChanged(object sender, EventArgs<int> e) {
+      EvalBestKnownSolution();
+    }
+    #endregion
+  }
+}
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/SingleDepotVRP/CVRP/CVRPTW/CVRPPDTW/CVRPPDTWProblemInstance.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/SingleDepotVRP/CVRP/CVRPTW/CVRPPDTW/CVRPPDTWProblemInstance.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/ProblemInstances/SingleDepotVRP/CVRP/CVRPTW/CVRPPDTW/CVRPPDTWProblemInstance.cs	(revision 6856)
@@ -81,4 +81,8 @@
       }
     }
+
+    public int GetPickupDeliveryLocation(int city) {
+      return PickupDeliveryLocation[city];
+    }
     
     [StorableConstructor]
Index: branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Variants/PickupAndDelivery/IPickupAndDeliveryProblemInstance.cs
===================================================================
--- branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Variants/PickupAndDelivery/IPickupAndDeliveryProblemInstance.cs	(revision 6855)
+++ branches/VRP/HeuristicLab.Problems.VehicleRouting/3.4/Variants/PickupAndDelivery/IPickupAndDeliveryProblemInstance.cs	(revision 6856)
@@ -31,4 +31,6 @@
     IntArray PickupDeliveryLocation { get; }
     DoubleValue PickupViolationPenalty { get; set; }
+
+    int GetPickupDeliveryLocation(int city);
   }
 }
