Index: /branches/1955_DynamicVehicleRouting/Build.cmd
===================================================================
--- /branches/1955_DynamicVehicleRouting/Build.cmd	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/Build.cmd	(revision 16099)
@@ -0,0 +1,94 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=1
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+  ECHO Solution file %SELECTED% could not be found.
+  GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+  CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+  SET SELECTED=%SOLUTIONS.1%
+  ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+  GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number: 
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+  IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"==""  GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Debug]: 
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Debug
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+  
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :main
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims=	 " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+  IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%"=="1" (
+  ECHO Cleaning ...
+  %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Build /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.cs	(revision 16099)
@@ -0,0 +1,228 @@
+﻿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;
+using HeuristicLab.Problems.VehicleRouting.Views;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.PDPSimulation.Operators;
+
+namespace HeuristicLab.PDPSimulation.Views {
+  [View("DynPDP View")]
+  [Content(typeof(DynPDPProblemInstance), true)]
+  public partial class DynPDPView : VRPProblemInstanceView {
+    public new DynPDPProblemInstance Content {
+      get { return (DynPDPProblemInstance)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DynPDPView() {
+      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 depotCoordinates = Content.DepotCoordinates;
+      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;
+      WaitingStrategy waitingStrategy = Content.WaitingStrategy;
+
+      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 && !Solution.GetTours().Exists(t => t.Stops.Exists(s => s > Content.Coordinates.Rows - Content.DepotCoordinates.Rows))) {
+            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)
+                  location = -1; //depot
+                else if (i == tour.Stops.Count)
+                  location = 0; //depot
+                else
+                  location = tour.Stops[i];
+
+                Point locationPoint;
+                if (location == -1) {
+                  locationPoint = new Point(border + ((int)((coordinates[depot, 0] - xMin) * xStep)),
+                                  bitmap.Height - (border + ((int)((coordinates[depot, 1] - yMin) * yStep))));
+                  location = 0;
+                } else if (location == 0) {
+                  locationPoint = new Point(border + ((int)((depotCoordinates[depot, 0] - xMin) * xStep)),
+                                  bitmap.Height - (border + ((int)((depotCoordinates[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) {
+                  t = readyTime[depot];
+                }
+                else if (i != tour.Stops.Count) {
+                  Brush customerBrush = Brushes.Black;
+                  Pen customerPen = Pens.Black;
+
+                  t += waitingStrategy.GetWaitingTime(t, Content, Solution, tour, i); 
+
+                  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) {
+                Pen pen = pens[((currentTour >= pens.Length) ? (pens.Length - 1) : (currentTour))];
+                for (int i = 1; i < tourPoints.Length; i++) {
+                  Point start = tourPoints[i - 1];
+                  Point end = tourPoints[i];
+
+                  graphics.DrawLine(pen, start, end);
+                }
+              }
+
+              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[cities];
+              //just draw customers
+              for (int i = 0; i < cities; i++) {
+                locationPoints[i] = new Point(border + ((int)((Content.GetCoordinates(i + 1)[0] - xMin) * xStep)),
+                                bitmap.Height - (border + ((int)((Content.GetCoordinates(i + 1)[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] - 1], locationPoints[i]);
+                  }
+                }
+              }
+
+              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/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.designer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.designer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/DynPDPView.designer.cs	(revision 16099)
@@ -0,0 +1,31 @@
+﻿namespace HeuristicLab.PDPSimulation.Views {
+  partial class DynPDPView {
+    /// <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/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/HeuristicLab.PDPSimulation.Views-3.3.csproj
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/HeuristicLab.PDPSimulation.Views-3.3.csproj	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/HeuristicLab.PDPSimulation.Views-3.3.csproj	(revision 16099)
@@ -0,0 +1,264 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{08FBD39B-C785-4199-BA39-A7AB87E364C6}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.PDPSimulation.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.PDPSimulation.Views-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.PDPSimulation.Views-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.PDPSimulation.Views-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.PDPSimulation.Views-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.PDPSimulation.Views-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.VehicleRouting-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.VehicleRouting-3.4.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.VehicleRouting.Views-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.VehicleRouting.Views-3.4.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="VehicleHistoryView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="VehicleHistoryView.Designer.cs">
+      <DependentUpon>VehicleHistoryView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DynPDPView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DynPDPView.designer.cs">
+      <DependentUpon>DynPDPView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="PickupDeliveryScenarioView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PickupDeliveryScenarioView.Designer.cs">
+      <DependentUpon>PickupDeliveryScenarioView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="PickupDeliveryVisualizationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="PickupDeliveryVisualizationView.Designer.cs">
+      <DependentUpon>PickupDeliveryVisualizationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Resources.Designer.cs">
+      <DependentUpon>Resources.resx</DependentUpon>
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.PDPSimulation\3.3\HeuristicLab.PDPSimulation-3.3.csproj">
+      <Project>{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}</Project>
+      <Name>HeuristicLab.PDPSimulation-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\depot.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\source.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\target.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Resources\truck.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Resources\truck_idle.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.Designer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.Designer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.Designer.cs	(revision 16099)
@@ -0,0 +1,69 @@
+﻿namespace HeuristicLab.PDPSimulation.Views {
+  partial class PickupDeliveryScenarioView {
+    /// <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 Component 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.importButton = new System.Windows.Forms.Button();
+      this.SuspendLayout();
+      // 
+      // importButton
+      // 
+      this.importButton.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.importButton.Location = new System.Drawing.Point(0, 26);
+      this.importButton.Name = "importButton";
+      this.importButton.Size = new System.Drawing.Size(529, 23);
+      this.importButton.TabIndex = 3;
+      this.importButton.Text = "&Import";
+      this.importButton.UseVisualStyleBackColor = true;
+      this.importButton.Click += new System.EventHandler(this.importButton_Click);
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.parameterCollectionView.Caption = "ParameterCollection View";
+      this.parameterCollectionView.Content = null;
+      this.parameterCollectionView.Location = new System.Drawing.Point(6, 50);
+      this.parameterCollectionView.Name = "parameterCollectionView";
+      this.parameterCollectionView.ReadOnly = false;
+      this.parameterCollectionView.Size = new System.Drawing.Size(509, 303);
+      this.parameterCollectionView.TabIndex = 0;
+      // 
+      // PickupDeliveryVisualizationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.importButton);
+      this.Name = "PickupDeliveryScenarioView";
+      this.Size = new System.Drawing.Size(529, 422);
+      this.Controls.SetChildIndex(this.importButton, 0);
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button importButton;
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.cs	(revision 16099)
@@ -0,0 +1,39 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Optimization.Views;
+
+namespace HeuristicLab.PDPSimulation.Views {
+  [View("PickupDeliveryScenario View")]
+  [Content(typeof(PickupDeliveryScenario), true)]
+  public partial class PickupDeliveryScenarioView : ProblemView {
+    public new PickupDeliveryScenario Content {
+      get { return (PickupDeliveryScenario)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public PickupDeliveryScenarioView() {
+      InitializeComponent();
+    }
+
+    private void importButton_Click(object sender, System.EventArgs e) {
+      OpenFileDialog dlg = new OpenFileDialog();
+      dlg.Filter = "dynamic PDP files (*.dpd)|*.dpd|dynamic PDP files - TSPLib (*.pdp*)|*.pdp";
+
+      if (dlg.ShowDialog() == DialogResult.OK) {
+        if (dlg.FilterIndex == 1)
+          Content.ImportFromDynPDP(dlg.FileName);
+        else
+          Content.ImportFromDynTSPLib(dlg.FileName);
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.resx
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.resx	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryScenarioView.resx	(revision 16099)
@@ -0,0 +1,129 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>107, 17</value>
+  </metadata>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>107, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.Designer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.Designer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.Designer.cs	(revision 16099)
@@ -0,0 +1,57 @@
+﻿namespace HeuristicLab.PDPSimulation.Views {
+  partial class PickupDeliveryVisualizationView {
+    /// <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 Component 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.pictureBox = new System.Windows.Forms.PictureBox();
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.pictureBox.Location = new System.Drawing.Point(0, 0);
+      this.pictureBox.Name = "pictureBox";
+      this.pictureBox.Size = new System.Drawing.Size(694, 462);
+      this.pictureBox.TabIndex = 0;
+      this.pictureBox.TabStop = false;
+      this.pictureBox.MouseClick += new System.Windows.Forms.MouseEventHandler(pictureBox_MouseClick);
+      // 
+      // PickupDeliveryVisualizationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.pictureBox);
+      this.Name = "PickupDeliveryVisualizationView";
+      this.Size = new System.Drawing.Size(694, 462);
+      this.SizeChanged += new System.EventHandler(this.PickupDeliveryVisualizationView_SizeChanged);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.PictureBox pictureBox;
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/PickupDeliveryVisualizationView.cs	(revision 16099)
@@ -0,0 +1,217 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.PDPSimulation.Views {
+  [View("PickupDeliveryVisualization View")]
+  [Content(typeof(PickupDeliveryVisualization), true)]
+  public partial class PickupDeliveryVisualizationView : ItemView {    
+    public new PickupDeliveryVisualization Content {
+      get { return (PickupDeliveryVisualization)base.Content; }
+      set { base.Content = value; }
+    }
+    
+    public PickupDeliveryVisualizationView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ContentChanged -= new EventHandler(Content_ContentChanged);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ContentChanged += new EventHandler(Content_ContentChanged);
+    }
+
+    void Content_ContentChanged(object sender, EventArgs e) {
+      GenerateImage();
+    }
+
+    private bool drawRoutes = false;
+
+    void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
+      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
+        drawRoutes = !drawRoutes;
+        GenerateImage();
+      }
+    }
+
+    private void GenerateImage() {
+      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
+        PickupDeliveryVisualization content = Content;
+
+        if (content == null) {
+          pictureBox.Image = null;
+        } else {          
+          int customerSize = Resources.source.Width;
+          int depotSize = Resources.depot.Width;
+          int truckSize = Resources.truck.Width;
+
+          int border = customerSize * 2;
+
+          Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+          double width = bitmap.Width - border * 2;
+          double height = bitmap.Height - border * 2;
+
+          double rangeX = content.OrderRangeX;
+          double rangeY = content.OrderRangeY;
+
+          using (Graphics graphics = Graphics.FromImage(bitmap)) {
+            if (drawRoutes) {
+              float completedWidth = 1;
+              Pen[] pastPens = {new Pen(Color.FromArgb(92,20,237), completedWidth), new Pen(Color.FromArgb(237,183,20), completedWidth), new Pen(Color.FromArgb(237,20,219), completedWidth), new Pen(Color.FromArgb(20,237,76), completedWidth),
+                    new Pen(Color.FromArgb(237,61,20), completedWidth), new Pen(Color.FromArgb(115,78,26), completedWidth), new Pen(Color.FromArgb(20,237,229), completedWidth), new Pen(Color.FromArgb(39,101,19), completedWidth),
+                    new Pen(Color.FromArgb(230,170,229), completedWidth), new Pen(Color.FromArgb(142,136,89), completedWidth), new Pen(Color.FromArgb(157,217,166), completedWidth), new Pen(Color.FromArgb(31,19,101), completedWidth),
+                    new Pen(Color.FromArgb(173,237,20), completedWidth), new Pen(Color.FromArgb(230,231,161), completedWidth), new Pen(Color.FromArgb(142,89,89), completedWidth), new Pen(Color.FromArgb(93,89,142), completedWidth),
+                    new Pen(Color.FromArgb(146,203,217), completedWidth), new Pen(Color.FromArgb(101,19,75), completedWidth), new Pen(Color.FromArgb(198,20,237), completedWidth), new Pen(Color.FromArgb(185,185,185), completedWidth),
+                    new Pen(Color.FromArgb(179,32,32), completedWidth), new Pen(Color.FromArgb(18,119,115), completedWidth), new Pen(Color.FromArgb(104,158,239), completedWidth), new Pen(Color.Black, completedWidth)};
+
+              float toBeServedWidth = 2;
+              Pen[] futurePens = {new Pen(Color.FromArgb(92,20,237), toBeServedWidth), new Pen(Color.FromArgb(237,183,20), toBeServedWidth), new Pen(Color.FromArgb(237,20,219), toBeServedWidth), new Pen(Color.FromArgb(20,237,76), toBeServedWidth),
+                    new Pen(Color.FromArgb(237,61,20), toBeServedWidth), new Pen(Color.FromArgb(115,78,26), toBeServedWidth), new Pen(Color.FromArgb(20,237,229), toBeServedWidth), new Pen(Color.FromArgb(39,101,19), toBeServedWidth),
+                    new Pen(Color.FromArgb(230,170,229), toBeServedWidth), new Pen(Color.FromArgb(142,136,89), toBeServedWidth), new Pen(Color.FromArgb(157,217,166), toBeServedWidth), new Pen(Color.FromArgb(31,19,101), toBeServedWidth),
+                    new Pen(Color.FromArgb(173,237,20), toBeServedWidth), new Pen(Color.FromArgb(230,231,161), toBeServedWidth), new Pen(Color.FromArgb(142,89,89), toBeServedWidth), new Pen(Color.FromArgb(93,89,142), toBeServedWidth),
+                    new Pen(Color.FromArgb(146,203,217), toBeServedWidth), new Pen(Color.FromArgb(101,19,75), toBeServedWidth), new Pen(Color.FromArgb(198,20,237), toBeServedWidth), new Pen(Color.FromArgb(185,185,185), toBeServedWidth),
+                    new Pen(Color.FromArgb(179,32,32), toBeServedWidth), new Pen(Color.FromArgb(18,119,115), toBeServedWidth), new Pen(Color.FromArgb(104,158,239), toBeServedWidth), new Pen(Color.Black, toBeServedWidth)};
+
+              int currentTour = 0;
+              foreach (Vehicle vehicle in content.Vehicles) {
+                PDAction action = content.GetAction(vehicle);
+                List<Point> tourPoints = new List<Point>();
+
+                while (action != null && action.ActionCompleted()) {
+                  if (action is MoveVehicleAction) {
+                    MoveVehicleAction moveAction = action as MoveVehicleAction;
+
+                    if (tourPoints.Count == 0) {
+                      tourPoints.Add(new Point((int)(border + moveAction.SourceX / rangeX * width),
+                        (int)(height + border - moveAction.SourceY / rangeY * height)));
+                    }
+
+                    Point locationPoint = new Point((int)(border + moveAction.TargetX / rangeX * width),
+                      (int)(height + border - moveAction.TargetY / rangeY * height));
+
+                    tourPoints.Add(locationPoint);
+                  }
+
+                  action = action.Successor;
+                }
+
+                if (tourPoints.Count > 1) {
+                  graphics.DrawLines(pastPens[((currentTour >= pastPens.Length) ? (pastPens.Length - 1) : (currentTour))], tourPoints.ToArray());
+
+                  Point last = tourPoints.Last();
+                  tourPoints.Clear();
+                  tourPoints.Add(last);
+                }
+
+                while (action != null) {
+                  if (action is MoveVehicleAction) {
+                    MoveVehicleAction moveAction = action as MoveVehicleAction;
+
+                    if (tourPoints.Count > 0 || (moveAction.SourceX >= 0 && moveAction.SourceY >= 0)) {
+                      if (tourPoints.Count == 0) {
+                        tourPoints.Add(new Point((int)(border + moveAction.SourceX / rangeX * width),
+                          (int)(height + border - moveAction.SourceY / rangeY * height)));
+                      }
+
+                      Point locationPoint = new Point((int)(border + moveAction.TargetX / rangeX * width),
+                        (int)(height + border - moveAction.TargetY / rangeY * height));
+
+                      tourPoints.Add(locationPoint);
+                    }
+                  }
+
+                  action = action.Successor;
+                }
+
+                if (tourPoints.Count > 1) {
+                  graphics.DrawLines(futurePens[((currentTour >= futurePens.Length) ? (futurePens.Length - 1) : (currentTour))], tourPoints.ToArray());
+                  currentTour++;
+                } 
+              }
+
+              for (int i = 0; i < pastPens.Length; i++)
+                pastPens[i].Dispose();
+              for (int i = 0; i < futurePens.Length; i++)
+                futurePens[i].Dispose();
+            } else {
+              using (Pen flowPen = new Pen(Brushes.Green)) {
+                flowPen.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
+                //flowPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
+
+                foreach (Order order in content.Orders) {
+                  if (order.OrderState != OrderState.Cancelled &&
+                    order.OrderState != OrderState.Delivered) {
+                    Point pickup = new Point(
+                      (int)(border + order.PickupXCoord / rangeX * width),
+                      (int)(height + border - order.PickupYCoord / rangeY * height));
+
+                    graphics.DrawImage(Resources.source, pickup.X - customerSize / 2, pickup.Y - customerSize / 2);
+
+                    if (!order.ServiceRequest) {
+                      Point delivery = new Point(
+                        (int)(border + order.DeliveryXCoord / rangeX * width),
+                        (int)(height + border - order.DeliveryYCoord / rangeY * height));
+
+                      graphics.DrawImage(Resources.target, delivery.X - customerSize / 2, delivery.Y - customerSize / 2);
+
+                      graphics.DrawLine(flowPen, pickup, delivery);
+                    }
+                  }
+                }
+              }
+            }
+
+            foreach (Vehicle vehicle in content.Vehicles) {
+              Point depotPoint = new Point(
+                (int)(border + vehicle.DepotX / rangeX * width),
+                (int)(height + border - vehicle.DepotY / rangeY * height));
+
+              graphics.DrawImage(Resources.depot, depotPoint.X - depotSize / 2,
+                depotPoint.Y - depotSize / 2);
+            }
+
+            foreach (Vehicle vehicle in content.Vehicles) {
+              Point vehiclePoint = new Point(
+                (int)(border + vehicle.PositionX / rangeX * width),
+                (int)(height + border - vehicle.PositionY / rangeY * height));
+
+              if (vehicle.VehicleState == VehicleState.Waiting || 
+                vehicle.VehicleState == VehicleState.Parked || 
+                vehicle.VehicleState == VehicleState.InvalidAction) {
+                graphics.DrawImage(Resources.truck_idle, vehiclePoint.X - truckSize / 2,
+                  vehiclePoint.Y - truckSize / 2);
+              } else {
+                graphics.DrawImage(Resources.truck, vehiclePoint.X - truckSize / 2,
+                  vehiclePoint.Y - truckSize / 2);
+              }
+            }
+          }
+          pictureBox.Image = bitmap;
+        }
+      }
+    }
+
+    private void PickupDeliveryVisualizationView_SizeChanged(object sender, EventArgs e) {
+      GenerateImage();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      GenerateImage();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Plugin.cs.frame
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Plugin.cs.frame	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Plugin.cs.frame	(revision 16099)
@@ -0,0 +1,43 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.PDPSimulation.Views {
+  /// <summary>
+  /// Plugin class for HeuristicLab.PDPSimulationViews plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.PDPSimulation.Views", "3.3.4.$WCREV$")]
+  [PluginFile("HeuristicLab.PDPSimulation.Views-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.PDPSimulation", "3.3")]
+  public class HeuristicLabPDPSimulationViewsPlugin : PluginBase {
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 16099)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.PDPSimulation.Views")]
+[assembly: AssemblyDescription("HeuristicLab pickup and delivery simulation")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("35402752-9A80-4757-9063-149BA096B7C7")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.4.$WCREV$")]
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.Designer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.Designer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.Designer.cs	(revision 16099)
@@ -0,0 +1,98 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.468
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace HeuristicLab.PDPSimulation.Views {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HeuristicLab.PDPSimulation.Views.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        internal static System.Drawing.Bitmap depot {
+            get {
+                object obj = ResourceManager.GetObject("depot", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Bitmap source {
+            get {
+                object obj = ResourceManager.GetObject("source", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Bitmap target {
+            get {
+                object obj = ResourceManager.GetObject("target", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Bitmap truck {
+            get {
+                object obj = ResourceManager.GetObject("truck", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+        
+        internal static System.Drawing.Bitmap truck_idle {
+            get {
+                object obj = ResourceManager.GetObject("truck_idle", resourceCulture);
+                return ((System.Drawing.Bitmap)(obj));
+            }
+        }
+    }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.resx
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.resx	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/Resources.resx	(revision 16099)
@@ -0,0 +1,136 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+  <data name="depot" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>resources\depot.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="source" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>resources\source.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="target" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>resources\target.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="truck" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>resources\truck.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+  <data name="truck_idle" type="System.Resources.ResXFileRef, System.Windows.Forms">
+    <value>resources\truck_idle.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+  </data>
+</root>
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.Designer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.Designer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.Designer.cs	(revision 16099)
@@ -0,0 +1,57 @@
+﻿namespace HeuristicLab.PDPSimulation.Views {
+  partial class VehicleHistoryView {
+    /// <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 Component 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.pictureBox = new System.Windows.Forms.PictureBox();
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.pictureBox.Location = new System.Drawing.Point(0, 0);
+      this.pictureBox.Name = "pictureBox";
+      this.pictureBox.Size = new System.Drawing.Size(694, 462);
+      this.pictureBox.TabIndex = 0;
+      this.pictureBox.TabStop = false;
+      this.pictureBox.MouseClick += new System.Windows.Forms.MouseEventHandler(pictureBox_MouseClick);
+      // 
+      // PickupDeliveryVisualizationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.pictureBox);
+      this.Name = "PickupDeliveryVisualizationView";
+      this.Size = new System.Drawing.Size(694, 462);
+      this.SizeChanged += new System.EventHandler(this.VehicleHistoryView_SizeChanged);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.PictureBox pictureBox;
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation.Views/3.3/VehicleHistoryView.cs	(revision 16099)
@@ -0,0 +1,178 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Analysis;
+
+namespace HeuristicLab.PDPSimulation.Views {
+  [View("VehicleHistoryView")]
+  [Content(typeof(VehicleHistoryVisualization), true)]
+  public partial class VehicleHistoryView : ItemView {
+    public new VehicleHistoryVisualization Content {
+      get { return (VehicleHistoryVisualization)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public VehicleHistoryView() {
+      InitializeComponent();
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ContentChanged -= new EventHandler(Content_ContentChanged);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ContentChanged += new EventHandler(Content_ContentChanged);
+    }
+
+    void Content_ContentChanged(object sender, EventArgs e) {
+      GenerateImage();
+    }
+
+    void pictureBox_MouseClick(object sender, System.Windows.Forms.MouseEventArgs e) {
+      if (e.Button == System.Windows.Forms.MouseButtons.Right) {
+        GenerateImage();
+      }
+    }
+
+    private List<Order> GetServicedOrders(VehicleHistory vehicle) {
+      List<Order> result = new List<Order>();
+
+      Order current = null;
+      for (int i = 0; i < vehicle.VehicleState.Count; i++) {
+        current = vehicle.ActiveOrders[i];
+        if (vehicle.VehicleState[i] == VehicleState.Servicing && !result.Contains(current))
+          result.Add(current);
+      }
+
+      return result;
+    }
+
+    private void GenerateImage() {
+      if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) {
+        VehicleHistoryVisualization content = Content;
+
+        if (content == null) {
+          pictureBox.Image = null;
+        } else {
+          Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height);
+          using (Graphics graphics = Graphics.FromImage(bitmap)) {
+            IEnumerable<VehicleHistory> vehicles = content.VehicleHistory.Where(v => v.VehicleState.Any(s => s != VehicleState.Parked && s != VehicleState.Waiting));
+            int vehicleCount = vehicles.Count();
+
+            if (vehicleCount > 0) {
+              float width = pictureBox.Width - 1;
+              float height = pictureBox.Height - 1;
+
+              int orderCount = 0;
+              foreach (VehicleHistory vehicle in vehicles)
+                orderCount += GetServicedOrders(vehicle).Count;
+
+              int totalRows = vehicleCount * 3 + orderCount;
+              float rowHeight = height / (float)totalRows;
+
+              int totalColumns = vehicles.First().VehicleState.Count;
+              float columnWidth = width / (float)totalColumns;
+              float timeWidth = columnWidth / (float)content.ResultCollectionInterval;
+
+              float curY = 0;
+              foreach (VehicleHistory vehicle in vehicles) {
+                float curX = 0;
+
+                int curAvailability = 1;
+                VehicleState curState = VehicleState.Parked;
+                int counter = 0;
+                for (int i = 0; i <= vehicle.VehicleState.Count; i++) {
+                  counter++;
+
+                  int availability = 1;
+                  VehicleState state = VehicleState.Parked;
+                  if (i < vehicle.VehicleState.Count) {
+                    state = vehicle.VehicleState[i];
+                    availability = vehicle.VehicleAvailability[i];
+                  }
+
+                  if (state != curState || availability != curAvailability || (i == vehicle.VehicleState.Count && i != 0)) {
+                    float stateWidth = columnWidth * (float)counter;
+
+                    Brush brush = Brushes.White;
+                    if (curAvailability <= 0)
+                      brush = Brushes.DarkGray;
+                    if (curState == VehicleState.Moving)
+                      brush = Brushes.Green;
+                    else if (curState == VehicleState.Servicing)
+                      brush = Brushes.Red;
+                    else if (curState == VehicleState.InvalidAction)
+                      brush = Brushes.Gray;
+
+                    graphics.FillRectangle(brush, curX, curY, stateWidth, rowHeight);
+
+                    curState = state;
+                    curAvailability = availability;
+                    counter = 0;
+                    curX += stateWidth;
+                  } 
+                }
+
+                graphics.DrawRectangle(Pens.Black, 0, curY, width, rowHeight);
+                            
+                curY += rowHeight;
+                curY += rowHeight;
+
+                foreach (Order order in GetServicedOrders(vehicle)) {
+                  float begin = Math.Min(pictureBox.Width, (float)order.PickupReadyTime * timeWidth);
+                  float end = Math.Min(pictureBox.Width, (float)order.PickupDueTime * timeWidth);
+                  graphics.DrawLine(Pens.Blue, begin, curY + rowHeight / 2, end, curY + rowHeight / 2);
+                  graphics.DrawLine(Pens.Blue, begin, curY, begin, curY + rowHeight);
+                  graphics.DrawLine(Pens.Blue, end, curY, end, curY + rowHeight);
+
+                  if (order.OrderState != OrderState.Waiting) {
+                    float pickupTime = Math.Min(width, (float)order.PickupTime * timeWidth);
+                    graphics.FillEllipse(Brushes.Blue, pickupTime - rowHeight / 4, curY + rowHeight / 4, rowHeight / 2, rowHeight / 2);
+                  }
+
+                  if (!order.ServiceRequest) {
+                    begin = Math.Min(pictureBox.Width, (float)order.DeliveryReadyTime * timeWidth);
+                    end = Math.Min(pictureBox.Width, (float)order.DeliveryDueTime * timeWidth);
+                    graphics.DrawLine(Pens.Green, begin, curY + rowHeight / 2, end, curY + rowHeight / 2);
+                    graphics.DrawLine(Pens.Green, begin, curY, begin, curY + rowHeight);
+                    graphics.DrawLine(Pens.Green, end, curY, end, curY + rowHeight);
+
+                    if (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp && order.OrderState != OrderState.PickedUp) {
+                      float deliveryTime = Math.Min(width, (float)order.DeliveryTime * timeWidth);
+                      graphics.FillEllipse(Brushes.Green, deliveryTime - rowHeight / 4, curY + rowHeight / 4, rowHeight / 2, rowHeight / 2);
+                    }
+                  }
+                  
+                  curY += rowHeight;
+                }
+
+                curY += rowHeight;
+              }
+            }
+            pictureBox.Image = bitmap;
+          }
+        }
+      }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      GenerateImage();
+    }
+
+    private void VehicleHistoryView_SizeChanged(object sender, EventArgs e) {
+      GenerateImage();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixData.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixData.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixData.cs	(revision 16099)
@@ -0,0 +1,67 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.PDPSimulation.DistanceMeasures {
+  [StorableClass]
+  public class DistanceMatrixData: ParameterizedNamedItem, IStorableContent {
+    public ValueParameter<DoubleMatrix> DistanceMatrixParameter {
+      get { return (ValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    public DoubleMatrix DistanceMatrix {
+      get {
+        return DistanceMatrixParameter.Value;
+      }
+
+      set {
+        DistanceMatrixParameter.Value = value;
+      }
+    }
+
+    public ValueParameter<IntMatrix> PointMappingParameter {
+      get { return (ValueParameter<IntMatrix>)Parameters["PointMapping"]; }
+    }
+
+    public IntMatrix Mapping {
+      get {
+        return PointMappingParameter.Value;
+      }
+
+      set {
+        PointMappingParameter.Value = value;
+      }
+    }
+
+    public DistanceMatrixData()
+      : base() {
+        Parameters.Add(new ValueParameter<DoubleMatrix>("DistanceMatrix", new DoubleMatrix()));
+        Parameters.Add(new ValueParameter<IntMatrix>("PointMapping", new IntMatrix()));
+    }
+    [StorableConstructor]
+    private DistanceMatrixData(bool deserializing) : base(deserializing) {
+    }
+    private DistanceMatrixData(DistanceMatrixData original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DistanceMatrixData(this, cloner);
+    }
+    
+    #region IStorableContent Members
+
+    public string Filename {
+      get;
+      set;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixMeasure.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixMeasure.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMatrixMeasure.cs	(revision 16099)
@@ -0,0 +1,151 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation.DistanceMeasures {
+  [StorableClass]
+  public class DistanceMatrixMeasure: DistanceMeasure {
+    private ValueParameter<DoubleMatrix> DistanceMatrixParameter {
+      get { return (ValueParameter<DoubleMatrix>)Parameters["DistanceMatrix"]; }
+    }
+
+    private ValueParameter<IntMatrix> PointMappingParameter {
+      get { return (ValueParameter<IntMatrix>)Parameters["PointMapping"]; }
+    }
+
+    private OptionalValueParameter<StringArray> PointNamesParameter {
+      get { return (OptionalValueParameter<StringArray>)Parameters["PointNames"]; }
+    }
+
+    public DoubleMatrix DistanceMatrix {
+      get {
+        return DistanceMatrixParameter.Value;
+      }
+      set {
+        DistanceMatrixParameter.Value = value;
+      }
+    }
+
+    public IntMatrix PointMapping {
+      get {
+        return PointMappingParameter.Value;
+      }
+      set {
+        PointMappingParameter.Value = value;
+      }
+    }
+
+    public StringArray PointNames {
+      get {
+        return PointNamesParameter.Value;
+      }
+      set {
+        PointNamesParameter.Value = value;
+      }
+    }
+
+    public DistanceMatrixMeasure()
+      : base() {
+        Parameters.Add(new ValueParameter<DoubleMatrix>("DistanceMatrix", new DoubleMatrix()));
+        Parameters.Add(new ValueParameter<IntMatrix>("PointMapping", new IntMatrix()));
+        Parameters.Add(new OptionalValueParameter<StringArray>("PointNames"));
+
+        DistanceMatrixParameter.GetsCollected = false;
+        PointMappingParameter.GetsCollected = false;
+        PointNamesParameter.GetsCollected = false;
+    }
+    [StorableConstructor]
+    protected DistanceMatrixMeasure(bool deserializing) : base(deserializing) {
+    }
+    protected DistanceMatrixMeasure(DistanceMatrixMeasure original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DistanceMatrixMeasure(this, cloner);
+    }
+
+    public override bool DiversionSupported {
+      get { return false; }
+    }
+
+    public int GetMapping(double x, double y) {
+      IntMatrix pointMapping = PointMappingParameter.Value;
+      int index = -1;
+
+      int ix = (int)Math.Round(x);
+      int iy = (int)Math.Round(y);
+
+      int i = 0;
+      while (index < 0 && i < pointMapping.Rows) {
+        if (pointMapping[i, 0] == ix && pointMapping[i, 1] == iy) {
+          index = i;
+        }         
+        i++;
+      }
+
+      return index;
+    }
+
+    protected double GetEuclideanDistance(double sourceX, double sourceY, double destX, double destY) {
+      double vx = destX - sourceX;
+      double vy = destY - sourceY;
+      double length = Math.Sqrt(vx * vx + vy * vy);
+
+      return length;
+    }
+
+    public override double GetDistance(double sourceX, double sourceY,
+      double currentX, double currentY, 
+      double destX, double destY) {
+      double total = GetEuclideanDistance(sourceX, sourceY, destX, destY);
+      double driven = GetEuclideanDistance(sourceX, sourceY, currentX, currentY);
+
+      double completed = 1.0;
+      if(total != 0)
+        completed = driven / total;
+
+      return GetDistance(sourceX, sourceY, destX, destY) * (1.0 - completed);
+    }
+
+    public override double GetDistance(double sourceX, double sourceY,
+     double destX, double destY) {
+      DoubleMatrix distanceMatrix = DistanceMatrixParameter.Value;
+
+      int i = GetMapping(sourceX, sourceY);
+      int j = GetMapping(destX, destY);
+
+      return distanceMatrix[i, j];
+    }
+
+    public override void Move(double sourceX, double sourceY,
+      double currentX, double currentY,
+      double destX, double destY, double time, Vehicle.MoveInformation moveInfo,
+      out double newPosX, out double newPosY, out double length) {
+      
+      length = GetDistance(sourceX, sourceY, currentX, currentY, destX, destY);
+      if (length < time) {
+        newPosX = destX;
+        newPosY = destY;
+      } else {
+        double step = GetEuclideanDistance(sourceX, sourceY, destX, destY) /
+          GetDistance(sourceX, sourceY, destX, destY);
+        double vx = destX - currentX;
+        double vy = destY - currentY;
+        double vl = GetEuclideanDistance(currentX, currentY, destX, destY);
+        vx = (vx / vl) * time * step;
+        vy = (vy / vl) * time * step;
+
+        newPosX = currentX + vx;
+        newPosY = currentY + vy;
+        length = time;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMeasure.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMeasure.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/DistanceMeasure.cs	(revision 16099)
@@ -0,0 +1,32 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation.DistanceMeasures {  
+  [StorableClass]
+  public abstract class DistanceMeasure: ParameterizedNamedItem {
+    public DistanceMeasure(): base() {
+    }
+
+    [StorableConstructor]
+    protected DistanceMeasure(bool deserializing) : base(deserializing) { }
+    protected DistanceMeasure(DistanceMeasure original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public abstract bool DiversionSupported { get; }
+    public abstract double GetDistance(double sourceX, double sourceY, double destX, double destY);
+    public abstract double GetDistance(double sourceX, double sourceY, 
+      double currentX, double currentY, 
+      double destX, double destY);
+    public abstract void Move(double sourceX, double sourceY,
+      double currentX, double currentY, 
+      double destX, double destY, double time, Vehicle.MoveInformation moveInfo,
+      out double newPosX, out double newPosY, out double length); 
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/EuclideanDistanceMeasure.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/EuclideanDistanceMeasure.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DistanceMeasures/EuclideanDistanceMeasure.cs	(revision 16099)
@@ -0,0 +1,68 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation.DistanceMeasures {
+  [StorableClass]
+  public class EuclideanDistanceMeasure: DistanceMeasure {
+    public EuclideanDistanceMeasure()
+      : base() {
+    }
+    [StorableConstructor]
+    private EuclideanDistanceMeasure(bool deserializing) : base(deserializing) {
+    }
+    private EuclideanDistanceMeasure(EuclideanDistanceMeasure original, Cloner cloner)
+      : base(original, cloner) {
+
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EuclideanDistanceMeasure(this, cloner);
+    }
+
+    public override bool DiversionSupported {
+      get { return true; }
+    }
+
+    public override double GetDistance(double sourceX, double sourceY,
+      double currentX, double currentY, 
+      double destX, double destY) {
+        return GetDistance(currentX, currentY, destX, destY);
+    }
+
+    public override double GetDistance(double sourceX, double sourceY,
+     double destX, double destY) {
+       double vx = destX - sourceX;
+       double vy = destY - sourceY;
+      double length = Math.Sqrt(vx * vx + vy * vy);
+
+      return length;
+    }
+
+    public override void Move(double sourceX, double sourceY,
+      double currentX, double currentY, 
+      double destX, double destY, double time, Vehicle.MoveInformation moveInfo, 
+      out double newPosX, out double newPosY, out double length) {
+      length = GetDistance(sourceX, sourceY, currentX, currentY, destX, destY);
+
+      if (length < time) {
+        newPosX = destX;
+        newPosY = destY;
+      } else {
+        double vx = destX - currentX;
+        double vy = destY - currentY;
+
+        vx = vx / length * time;
+        vy = vy / length * time;
+
+        newPosX = currentX + vx;
+        newPosY = currentY + vy;
+        length = time;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/BaseObject.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/BaseObject.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/BaseObject.cs	(revision 16099)
@@ -0,0 +1,38 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation.DomainModel {
+  [StorableClass]
+  public abstract class BaseObject: Item {
+    [Storable]
+    public Guid Id { get; set; }
+
+    public BaseObject() {
+      Id = Guid.NewGuid();
+    }
+
+    [StorableConstructor]
+    protected BaseObject(bool deserializing) : base(deserializing) { }
+    protected BaseObject(BaseObject original, Cloner cloner)
+      : base(original, cloner) {
+        Id = original.Id;
+    }
+
+    public override bool Equals(object obj) {
+      if (obj is BaseObject) {
+        return Id == (obj as BaseObject).Id;
+      } else {
+        return base.Equals(obj);
+      }
+    }
+
+    public override int GetHashCode() {
+      return Id.GetHashCode();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Order.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Order.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Order.cs	(revision 16099)
@@ -0,0 +1,111 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation.DomainModel {
+  public enum OrderState { Waiting, PickingUp, PickedUp, Delivering, Delivered, Cancelled }
+
+  [StorableClass]
+  public class Order: BaseObject {
+    //State
+    [Storable]
+    public OrderState OrderState { get; set; }
+    [Storable]
+    public double Tardiness { get; set; }
+    [Storable]
+    public double PickupTime { get; set; }
+    [Storable]
+    public double DeliveryTime { get; set; }
+    [Storable]
+    public Guid Vehicle { get; set; }
+    [Storable]
+    public Guid AssignedVehicle { get; set; }
+
+    //Data
+    [Storable]
+    public int Index { get; set; }
+    [Storable]
+    public bool ServiceRequest { get; set; }
+    [Storable]
+    public double PickupXCoord { get; set; }
+    [Storable]
+    public double PickupYCoord { get; set; }
+    [Storable]
+    public double DeliveryXCoord { get; set; }
+    [Storable]
+    public double DeliveryYCoord { get; set; }
+    [Storable]
+    public double Demand { get; set; }
+    [Storable]
+    public double PickupServiceTime { get; set; }
+    [Storable]
+    public double PickupReadyTime { get; set; }
+    [Storable]
+    public double PickupDueTime { get; set; }
+    [Storable]
+    public double DeliveryServiceTime { get; set; }
+    [Storable]
+    public double DeliveryReadyTime { get; set; }
+    [Storable]
+    public double DeliveryDueTime { get; set; }
+    [Storable]
+    public string Name { get; set; }
+
+    public Order()
+      : base() {
+    }
+    [StorableConstructor]
+    private Order(bool deserializing) : base(deserializing) {
+    }
+    private Order(Order original, Cloner cloner)
+      : base(original, cloner) {
+        Index = original.Index;
+        ServiceRequest = original.ServiceRequest;
+        OrderState = original.OrderState;
+        Tardiness = original.Tardiness;
+        PickupTime = original.PickupTime;
+        DeliveryTime = original.DeliveryTime;
+        Vehicle = original.Vehicle;
+        AssignedVehicle = original.AssignedVehicle;
+        PickupXCoord = original.PickupXCoord;
+        PickupYCoord = original.PickupYCoord;
+        DeliveryXCoord = original.DeliveryXCoord;
+        DeliveryYCoord = original.DeliveryYCoord;
+        Demand = original.Demand;
+        PickupServiceTime = original.PickupServiceTime;
+        PickupReadyTime = original.PickupReadyTime;
+        PickupDueTime = original.PickupDueTime;
+        DeliveryServiceTime = original.DeliveryServiceTime;
+        DeliveryReadyTime = original.DeliveryReadyTime;
+        DeliveryDueTime = original.DeliveryDueTime;
+        Name = original.Name;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Order(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/SimulationObject.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/SimulationObject.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/SimulationObject.cs	(revision 16099)
@@ -0,0 +1,45 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation.DomainModel {
+  [StorableClass]
+  public class SimulationObject: BaseObject {
+    public SimulationObject()
+      : base() {
+    }
+    [StorableConstructor]
+    private SimulationObject(bool deserializing) : base(deserializing) {
+    }
+    private SimulationObject(SimulationObject original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimulationObject(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Vehicle.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Vehicle.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/DomainModel/Vehicle.cs	(revision 16099)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation.DomainModel {
+  public enum VehicleState { Parked, Waiting, InvalidAction, Moving, Servicing }
+
+  [StorableClass]
+  public class Vehicle: BaseObject {
+    //State
+    [Storable]
+    public VehicleState VehicleState { get; set; }
+    [Storable]
+    public List<Guid> PickedUpOrders { get; set; }
+    [Storable]
+    public double PositionX { get; set; }
+    [Storable]
+    public double PositionY { get; set; }
+    [Storable]
+    public double Overload { get; set; }
+    [Storable]
+    public double Distance { get; set; }
+    [Storable]
+    public double Capacity { get; set; }
+    [Storable]
+    public double ReadyTime { get; set; }
+    [Storable]
+    public int InvalidActions { get; set; }
+    [Storable]
+    public double Tardiness { get; set; }
+    [Storable]
+    public double TargetPositionX { get; set; }
+    [Storable]
+    public double TargetPositionY { get; set; }
+    [Storable]
+    public Guid CurrentOrder { get; set; }
+    [Storable]
+    public VehicleAction CurrentAction { get; set; }
+    [Storable]
+    public int Availibility { get; set; }
+    
+    [StorableClass]
+    public class MoveInformation {
+      [Storable]
+      public int Segment { get; set; }
+
+      [Storable]
+      public int Source { get; set; }
+
+      [Storable]
+      public int Dest { get; set; }
+
+      public object Path { get; set; }
+    }
+    
+    [Storable]
+    public MoveInformation MoveInfo { get; set; }
+    
+    //Data
+    [Storable]
+    public string Name { get; set; }
+    [Storable]
+    public double TotalCapacity { get; set; }
+    [Storable]
+    public double DepotX { get; set; }
+    [Storable]
+    public double DepotY { get; set; }
+    [Storable]
+    public double DueTime { get; set; }
+
+    public Vehicle()
+      : base() {
+        PickedUpOrders = new List<Guid>();
+        MoveInfo = new MoveInformation();
+    }
+    [StorableConstructor]
+    private Vehicle(bool deserializing) : base(deserializing) {
+    }
+    private Vehicle(Vehicle original, Cloner cloner)
+      : base(original, cloner) {
+        VehicleState = original.VehicleState;
+        PickedUpOrders = new List<Guid>(original.PickedUpOrders);
+        PositionX = original.PositionX;
+        PositionY = original.PositionY;
+        Overload = original.Overload;
+        Distance = original.Distance;
+        DepotX = original.DepotX;
+        DepotY = original.DepotY;
+        Capacity = original.Capacity;
+        ReadyTime = original.ReadyTime;
+        DueTime = original.DueTime;
+        InvalidActions = original.InvalidActions;
+        Tardiness = original.Tardiness;
+        TargetPositionX = original.TargetPositionX;
+        TargetPositionY = original.TargetPositionY;
+        CurrentOrder = original.CurrentOrder;
+        CurrentAction = original.CurrentAction;
+        TotalCapacity = original.TotalCapacity;
+        MoveInfo = new MoveInformation();
+        MoveInfo.Source = original.MoveInfo.Source;
+        MoveInfo.Dest = original.MoveInfo.Dest;
+        MoveInfo.Segment = original.MoveInfo.Segment;
+        Availibility = original.Availibility;
+        Name = original.Name;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Vehicle(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj	(revision 16099)
@@ -0,0 +1,270 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.PDPSimulation</RootNamespace>
+    <AssemblyName>HeuristicLab.PDPSimulation-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.PDPSimulation-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.PDPSimulation-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.PDPSimulation-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.PDPSimulation-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;C:\Program Files\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Accessibility">
+      <EmbedInteropTypes>True</EmbedInteropTypes>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.PermutationEncoding-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.PermutationEncoding-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.VehicleRouting-3.4">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.VehicleRouting-3.4.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+      <Private>false</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DistanceMeasures\DistanceMatrixData.cs" />
+    <Compile Include="DistanceMeasures\DistanceMatrixMeasure.cs" />
+    <Compile Include="DistanceMeasures\DistanceMeasure.cs" />
+    <Compile Include="DistanceMeasures\EuclideanDistanceMeasure.cs" />
+    <Compile Include="DomainModel\SimulationObject.cs" />
+    <Compile Include="Operators\TreePriorityDispatchingMetaOptEvaluator.cs" />
+    <Compile Include="Operators\PriorityDispatchingMetaOptEvaluator.cs" />
+    <Compile Include="Operators\DialARideEvaluator.cs" />
+    <Compile Include="Operators\DynPDPEvaluator.cs" />
+    <Compile Include="Operators\DynPushForwardInsertionCreator.cs" />
+    <Compile Include="Operators\DynPDPProblemInstance.cs" />
+    <Compile Include="Operators\LinearPriorityDispatchingMetaOptEvaluator.cs" />
+    <Compile Include="Optimizers\DynamicPDProblemInstance.cs" />
+    <Compile Include="Optimizers\DynamicPDPOptimization.cs" />
+    <Compile Include="Optimizers\LocalUpdate\BestInsertion.cs" />
+    <Compile Include="Optimizers\LocalUpdate\Dispatching.cs" />
+    <Compile Include="Optimizers\LocalUpdate\EarliestDueTimeDispatching.cs" />
+    <Compile Include="Optimizers\LocalUpdate\NearestDestinationDispatching.cs" />
+    <Compile Include="Optimizers\LocalUpdate\TreePriorityDispatching.cs" />
+    <Compile Include="Optimizers\LocalUpdate\LinearPriorityDispatching.cs" />
+    <Compile Include="Optimizers\LocalUpdate\PriorityDispatching.cs" />
+    <Compile Include="Optimizers\Reoptimization\PFIHReoptimization.cs" />
+    <Compile Include="Parsers\DefaultDynPDPParser.cs" />
+    <Compile Include="Parsers\DynPDPParser.cs" />
+    <Compile Include="Parsers\TSPLibDynPDPParser.cs" />
+    <Compile Include="PickupDeliveryAnalyzer.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="SimulationCore\IScenario.cs" />
+    <Compile Include="SimulationCore\ISimulation.cs" />
+    <Compile Include="SimulationCore\Scenario.cs" />
+    <Compile Include="SimulationCore\Simulation.cs" />
+    <Compile Include="SimulationModel\WaitAction.cs" />
+    <Compile Include="SimulationModel\PDChange.cs" />
+    <Compile Include="SimulationModel\MoveVehicleAction.cs" />
+    <Compile Include="SimulationModel\PDAction.cs" />
+    <Compile Include="DomainModel\BaseObject.cs" />
+    <Compile Include="DomainModel\Order.cs" />
+    <Compile Include="DomainModel\Vehicle.cs" />
+    <Compile Include="OrderGenerators\PickupDeliveryPredefinedOrderGenerator.cs" />
+    <Compile Include="PickupDeliveryOrderGenerator.cs" />
+    <Compile Include="PickupDeliveryOptimization.cs" />
+    <Compile Include="PickupDeliveryScenario.cs" />
+    <Compile Include="PickupDeliverySimulation.cs" />
+    <Compile Include="PickupDeliveryVisualization.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="VehicleHistoryVisualization.cs" />
+    <Compile Include="WaitingStrategies\WaitFirstWaitingStrategy.cs" />
+    <Compile Include="WaitingStrategies\DriveFirstWaitingStrategy.cs" />
+    <Compile Include="WaitingStrategies\WaitingStrategy.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DialARideEvaluator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DialARideEvaluator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DialARideEvaluator.cs	(revision 16099)
@@ -0,0 +1,296 @@
+﻿#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;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Encodings.General;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  public class DialARideEvaluation : DynPDPEvaluation {
+    public List<double> LeadTimes { get; private set; }
+
+    public DialARideEvaluation() {
+      LeadTimes = new List<double>();
+    } 
+  }
+
+  [Item("DialARideEvaluator", "Represents a dynamic multi depot CVRPPDTW evaluator.")]
+  [StorableClass]
+  public class DialARideEvaluator: DynPDPEvaluator {
+    public ILookupParameter<DoubleValue> LeadTimeParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["LeadTime"]; }
+    }
+
+    public IValueParameter<DoubleValue> LeadTimeFactorParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["LeadTimeFactor"]; }
+    }
+
+    protected override VRPEvaluation CreateTourEvaluation() {
+      return new DialARideEvaluation();
+    }
+
+    protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) {
+      TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour)));
+      eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
+      double originalQuality = eval.Quality;
+
+      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[depot];
+      time = tourStartTime;
+
+      WaitingStrategy waitingStrategy = (instance as DynPDPProblemInstance).WaitingStrategy;
+
+      List<double> leadTimes = new List<double>();
+
+      //simulate a tour
+      int count = tour.Stops.Count;
+      if (!(instance as DynPDPProblemInstance).RelocateBackToDepot)
+        count -= 1;
+      for (int i = 0; i <= 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];
+
+        //Waiting strategy...
+        if (end != 0) {
+          double waitAction = waitingStrategy.GetBufferTime(time, instance as DynPDPProblemInstance, solution, tour, i);
+          time += waitAction;
+        }
+
+        double commitmentTime = time;
+        
+        //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 += Math.Min(1000000, Math.Pow((vrptw.TardinessPenalty.Value * Math.E), (time - dueTime[endIndex])) - 1.0);
+
+        //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
+          int location = pickupDeliveryLocation[end - 1];
+          bool validPickupDelivery =
+            validPickupDelivery =
+            ((demand[end - 1] >= 0) ||
+             (end == location) ||
+             (location <= 0 && vehicle == -location) ||
+             (stops.ContainsKey(location)));
+
+          if (validPickupDelivery) {
+            currentLoad += demand[end - 1];
+
+            if (demand[end - 1] < 0) {
+              double pickupReady = 0;
+              if (location > 0) {
+                pickupReady = readyTime[location + depots - 1];
+              }
+              leadTimes.Add(time - currentServiceTime - pickupReady);
+            }
+          } else {
+            pickupViolations++;
+          }
+
+          if (currentLoad > capacity)
+            overweight += currentLoad - capacity;
+        }
+
+        double spareCapacity = capacity - currentLoad;
+        CVRPPDTWInsertionInfo stopInfo = new DynPDPInsertionInfo(start, end, spareCapacity, tourStartTime,
+          arrivalTime, time, spareTime, waitTime, commitmentTime, new List<int>(stops.Keys), arrivalSpareCapacity);
+        tourInfo.AddStopInsertionInfo(stopInfo);
+
+        stops.Add(end, true);
+      }
+
+      if(!(instance as DynPDPProblemInstance).VehicleUsed[vehicle])
+        eval.Quality += instance.FleetUsageFactor.Value;
+
+      eval.Quality += instance.DistanceFactor.Value * distance;
+      eval.Distance += distance;
+      eval.VehicleUtilization += 1;
+      double leadTime = 0;
+      if (leadTimes.Count > 0)
+        leadTime = leadTimes.Sum();
+      eval.Quality += leadTime * LeadTimeFactorParameter.Value.Value;
+
+      (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;
+      //eval.Penalty += penalty;
+      eval.Quality += tardiness;
+      //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;
+      tourInfo.Quality = eval.Quality - originalQuality;
+
+      (eval as DialARideEvaluation).LeadTimes.AddRange(leadTimes);
+    }
+
+    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, 
+      out bool feasible) {
+        TourEncoding individual = null;
+        if (solution is TourEncoding)
+          individual = solution as TourEncoding;
+        else {
+          individual = new PotvinEncoding(instance);
+          individual.Tours.AddRange(solution.GetTours());
+        }
+
+        int tourIdx = -1;
+        for (int i = 0; i < individual.Tours.Count; i++) {
+          if (solution.GetVehicleAssignment(i) == tourInsertionInfo.Vehicle)
+            tourIdx = i;
+        }
+        Tour tour = individual.Tours[tourIdx];
+
+        tour.Stops.Insert(index, customer);
+        VRPEvaluation newEval = instance.EvaluateTour(tour, individual);
+        tour.Stops.RemoveAt(index);
+
+        feasible = instance.Feasible(newEval);
+        return newEval.Quality - tourInsertionInfo.Quality;
+    }
+
+    protected override void InitResultParameters() {
+      base.InitResultParameters();
+
+      LeadTimeParameter.ActualValue = new DoubleValue(0);
+    }
+
+    protected override void SetResultParameters(VRPEvaluation tourEvaluation) {
+      base.SetResultParameters(tourEvaluation);
+
+      double leadTime = 0;
+      if((tourEvaluation as DialARideEvaluation).LeadTimes.Count > 0)
+        leadTime = (tourEvaluation as DialARideEvaluation).LeadTimes.Average();
+      LeadTimeParameter.ActualValue.Value = leadTime;
+    }
+    
+    [StorableConstructor]
+    protected DialARideEvaluator(bool deserializing) : base(deserializing) { }
+
+    public DialARideEvaluator() {
+      Parameters.Add(new LookupParameter<DoubleValue>("LeadTime", "The total lead time."));
+      Parameters.Add(new ValueParameter<DoubleValue>("LeadTimeFactor", "The lead time factor considered in the evaluation.", new DoubleValue(0)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DialARideEvaluator(this, cloner);
+    }
+
+    protected DialARideEvaluator(DialARideEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPEvaluator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPEvaluator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPEvaluator.cs	(revision 16099)
@@ -0,0 +1,344 @@
+﻿#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;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Encodings.General;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  public class DynPDPInsertionInfo : CVRPPDTWInsertionInfo {
+    private double commitmentTime;
+
+    public double CommitmentTime {
+      get { return commitmentTime; }
+    }
+
+
+    public DynPDPInsertionInfo(int start, int end, double spareCapacity, double tourStartTime,
+      double arrivalTime, double leaveTime, double spareTime, double waitingTime, double commitmentTime, 
+      List<int> visited, double arrivalSpareCapacity)
+      : base(start, end, spareCapacity, tourStartTime, arrivalTime, leaveTime, spareTime, waitingTime, visited, arrivalSpareCapacity) {
+        this.commitmentTime = commitmentTime;
+    }
+  }
+  
+  public class DynPDPEvaluation : CVRPPDTWEvaluation {
+    //public List<List<double>> WaitingTimes { get; private set; }
+
+    public DynPDPEvaluation() {
+      //WaitingTimes = new List<List<double>>();
+    } 
+  }
+  
+  [Item("DynPDPEvaluator", "Represents a dynamic multi depot CVRPPDTW evaluator.")]
+  [StorableClass]
+  public class DynPDPEvaluator: MDCVRPTWEvaluator {
+    public ILookupParameter<IntValue> PickupViolationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["PickupViolations"]; }
+    }
+
+    protected override VRPEvaluation CreateTourEvaluation() {
+      return new DynPDPEvaluation();
+    }
+
+    public static List<double> GetWaitingTimes(DynPDPProblemInstance instance, Tour tour, IVRPEncoding solution) {
+      DoubleArray dueTime = instance.DueTime;
+      DoubleArray readyTime = instance.ReadyTime;
+      DoubleArray serviceTimes = instance.ServiceTime;
+
+      IntArray vehicleAssignment = instance.VehicleDepotAssignment;
+      int depots = instance.Depots.Value;
+     
+      int tourIndex = solution.GetTourIndex(tour);
+      int vehicle = solution.GetVehicleAssignment(tourIndex);
+      int depot = vehicleAssignment[vehicle];
+
+      List<double> waitingTimes = new List<double>();
+      WaitingStrategy waitingStrategy = (instance as DynPDPProblemInstance).WaitingStrategy;
+
+      double time = readyTime[depot];
+      int count = tour.Stops.Count;
+      if (!(instance as DynPDPProblemInstance).RelocateBackToDepot)
+        count -= 1;
+      for (int i = 0; i <= 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];
+
+        //Waiting strategy...
+        if (end != 0) {
+          double waitAction = waitingStrategy.GetWaitingTime(time, instance as DynPDPProblemInstance, solution, tour, i);
+          waitingTimes.Add(waitAction);
+          time += waitAction;
+        }
+
+        //drive there
+        time += instance.GetDistance(start, end, solution);
+
+        int endIndex;
+        if (end == 0)
+          endIndex = depot;
+        else
+          endIndex = end + depots - 1;
+
+        //wait
+        if (time < readyTime[endIndex])
+          time = readyTime[endIndex];
+
+        if (end > 0) {
+          //service
+          time += serviceTimes[end - 1];
+        }
+      }
+
+      return waitingTimes;
+    }
+
+    protected override void EvaluateTour(VRPEvaluation eval, IVRPProblemInstance instance, Tour tour, IVRPEncoding solution) {
+      TourInsertionInfo tourInfo = new TourInsertionInfo(solution.GetVehicleAssignment(solution.GetTourIndex(tour)));
+      eval.InsertionInfo.AddTourInsertionInfo(tourInfo);
+      double originalQuality = eval.Quality;
+
+      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[depot];
+      time = tourStartTime;
+
+      WaitingStrategy waitingStrategy = (instance as DynPDPProblemInstance).WaitingStrategy;
+
+      //simulate a tour
+      int count = tour.Stops.Count;
+      if (!(instance as DynPDPProblemInstance).RelocateBackToDepot)
+        count -= 1;
+      for (int i = 0; i <= 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];
+
+        //Waiting strategy...
+        if (end != 0) {
+          double waitAction = waitingStrategy.GetBufferTime(time, instance as DynPDPProblemInstance, solution, tour, i);
+          time += waitAction;
+        }
+
+        double commitmentTime = time;
+        
+        //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
+          int location = pickupDeliveryLocation[end - 1];
+          bool validPickupDelivery =
+            validPickupDelivery =
+            ((demand[end - 1] >= 0) ||
+             (end == location) ||
+             (location <= 0 && vehicle == -location) ||
+             (stops.ContainsKey(location)));
+
+          if (validPickupDelivery) {
+            currentLoad += demand[end - 1];
+          } else {
+            pickupViolations++;
+          }
+
+          if (currentLoad > capacity)
+            overweight += currentLoad - capacity;
+        }
+
+        double spareCapacity = capacity - currentLoad;
+        CVRPPDTWInsertionInfo stopInfo = new DynPDPInsertionInfo(start, end, spareCapacity, tourStartTime,
+          arrivalTime, time, spareTime, waitTime, commitmentTime, new List<int>(stops.Keys), arrivalSpareCapacity);
+        tourInfo.AddStopInsertionInfo(stopInfo);
+
+        stops.Add(end, true);
+      }
+
+      if(!(instance as DynPDPProblemInstance).VehicleUsed[vehicle])
+        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;
+      tourInfo.Quality = eval.Quality - originalQuality;
+    }
+
+    protected override double GetTourInsertionCosts(IVRPProblemInstance instance, IVRPEncoding solution, TourInsertionInfo tourInsertionInfo, int index, int customer, 
+      out bool feasible) {
+        TourEncoding individual = null;
+        if (solution is TourEncoding)
+          individual = solution as TourEncoding;
+        else {
+          individual = new PotvinEncoding(instance);
+          individual.Tours.AddRange(solution.GetTours());
+        }
+
+        int tourIdx = -1;
+        for (int i = 0; i < individual.Tours.Count; i++) {
+          if (solution.GetVehicleAssignment(i) == tourInsertionInfo.Vehicle)
+            tourIdx = i;
+        }
+        Tour tour = individual.Tours[tourIdx];
+
+        tour.Stops.Insert(index, customer);
+        VRPEvaluation newEval = instance.EvaluateTour(tour, individual);
+        tour.Stops.RemoveAt(index);
+
+        feasible = instance.Feasible(newEval);
+        return newEval.Quality - tourInsertionInfo.Quality;
+    }
+
+    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 DynPDPEvaluator(bool deserializing) : base(deserializing) { }
+
+    public DynPDPEvaluator() {
+      Parameters.Add(new LookupParameter<IntValue>("PickupViolations", "The number of pickup violations."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynPDPEvaluator(this, cloner);
+    }
+
+    protected DynPDPEvaluator(DynPDPEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPProblemInstance.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPProblemInstance.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPDPProblemInstance.cs	(revision 16099)
@@ -0,0 +1,217 @@
+﻿#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;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+using System.Threading;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  [Item("DynPDPProblemInstance", "Represents a dynamic multi depot CVRPPDTW instance.")]
+  [StorableClass]
+  public class DynPDPProblemInstance: MDCVRPPDTWProblemInstance {
+    protected ValueParameter<DoubleMatrix> DepotCoordinatesParameter {
+      get { return (ValueParameter<DoubleMatrix>)Parameters["DepotCoordinates"]; }
+    }
+
+    protected ValueParameter<BoolArray> VehicleUsedParameter {
+      get { return (ValueParameter<BoolArray>)Parameters["VehicleUsed"]; }
+    }
+
+    [Storable]
+    public List<VehicleState> VehicleStates {
+      get;
+      set;
+    }
+
+    [Storable]
+    public PotvinEncoding CurrentPlan {
+      get;
+      set;
+    }
+
+    public BoolArray VehicleUsed {
+      get { return VehicleUsedParameter.Value; }
+      set { VehicleUsedParameter.Value = value; }
+    }
+
+    public DoubleMatrix DepotCoordinates {
+      get { return DepotCoordinatesParameter.Value; }
+      set { DepotCoordinatesParameter.Value = value; }
+    }
+
+    protected override IVRPCreator Creator {
+      get {
+        return new DynPushForwardInsertionCreator();
+      }
+    }
+    
+    protected override IVRPEvaluator Evaluator {
+      get {
+        return new DynPDPEvaluator();
+      }
+    }
+
+    public Barrier AlgorithmSyncObject {
+      get;
+      set;
+    }
+
+    public Barrier AnalyzerSyncObject {
+      get;
+      set;
+    }
+
+    [Storable]
+    private ResultCollection results;
+
+    public ResultCollection Results {
+      get {
+        return results;
+      }
+    }
+
+    [Storable]
+    private PickupDeliveryScenario scenario;
+
+    public bool RelocateBackToDepot {
+      get {
+        return scenario.RelocateBackToDepot;
+      }
+    }
+
+    public double Horizon {
+      get {
+        return scenario.VehicleDueTimesParameter.Value.Max();
+      }
+    }
+
+    [Storable]
+    protected WaitingStrategy waitingStrategy;
+
+    public WaitingStrategy WaitingStrategy {
+      get {
+        return waitingStrategy;
+      }
+
+      set {
+        waitingStrategy = value;
+      }
+    }
+    
+    [StorableConstructor]
+    protected DynPDPProblemInstance(bool deserializing) : base(deserializing) { }
+    
+    public DynPDPProblemInstance(PickupDeliveryScenario scenario, ResultCollection results)
+      : base() {
+      Parameters.Add(new ValueParameter<DoubleMatrix>("DepotCoordinates", "The x- and y-Coordinates of the depots.", new DoubleMatrix()));
+      Parameters.Add(new ValueParameter<BoolArray>("VehicleUsed", "Indicates, if a vehicle has been used.", new BoolArray()));
+
+      this.scenario = scenario;
+      this.results = results;
+      VehicleStates = new List<VehicleState>();
+
+      if (scenario != null) {
+        SolutionEvaluator = scenario.Evaluator;
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynPDPProblemInstance(this, cloner);
+    }
+
+    protected DynPDPProblemInstance(DynPDPProblemInstance original, Cloner cloner)
+      : base(original, cloner) {
+        this.scenario = cloner.Clone<PickupDeliveryScenario>(original.scenario);
+        this.SolutionEvaluator = cloner.Clone<IVRPEvaluator>(original.SolutionEvaluator);
+        this.results = cloner.Clone<ResultCollection>(original.results);
+        this.waitingStrategy = cloner.Clone<WaitingStrategy>(original.waitingStrategy);
+        this.VehicleStates = new List<VehicleState>(original.VehicleStates);
+        this.CurrentPlan = cloner.Clone<PotvinEncoding>(CurrentPlan);
+    }
+
+    public DynPDPProblemInstance ShallowClone() {
+      Cloner cloner = new Cloner();
+      return new DynPDPProblemInstance(this, cloner, true);
+    }
+
+    protected DynPDPProblemInstance(DynPDPProblemInstance original, Cloner cloner, bool shallow)
+      : base(original, cloner) {
+      this.scenario = original.scenario;
+      this.SolutionEvaluator = cloner.Clone<IVRPEvaluator>(original.SolutionEvaluator);
+      this.results = original.results;
+      this.waitingStrategy = original.waitingStrategy;
+      this.VehicleStates = original.VehicleStates;
+      this.CurrentPlan =  cloner.Clone<PotvinEncoding>(CurrentPlan);
+    }
+
+    protected override double CalculateDistance(int start, int end) {
+      double distance = 0.0;
+
+      if (end < Depots.Value) {
+        distance =
+          scenario.DistanceMeasure.GetDistance(Coordinates[start, 0], Coordinates[start, 1], DepotCoordinates[end, 0], DepotCoordinates[end, 1]); 
+      } else {
+        distance =
+          scenario.DistanceMeasure.GetDistance(Coordinates[start, 0], Coordinates[start, 1], Coordinates[end, 0], Coordinates[end, 1]);
+      }
+
+      return distance;
+    }
+
+    public double GetDistance(int start, int end) {
+      return CalculateDistance(start, end);
+    }
+
+    public double GetDistanceToDepot(int vehicle) {
+      return CalculateDistance(vehicle, vehicle);
+    }
+
+    public void ResetDistanceMatrix() {
+      UseDistanceMatrixParameter.Value = new BoolValue(false);
+      DistanceMatrixParameter.Value = null;
+
+      UseDistanceMatrixParameter.Value = new BoolValue(true);
+    }
+
+    public void Initialize() {
+      PickupViolationPenalty.Value = scenario.PickupViolationPenaltyParameter.Value.Value;
+      OverloadPenalty.Value = scenario.OverloadPenaltyParameter.Value.Value;
+      TardinessPenalty.Value = scenario.TardinessPenaltyParameter.Value.Value;
+      FleetUsageFactor.Value = scenario.FleetUsageFactorParameter.Value.Value;
+      DistanceFactor.Value = scenario.DistanceFactorParameter.Value.Value;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPushForwardInsertionCreator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPushForwardInsertionCreator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/DynPushForwardInsertionCreator.cs	(revision 16099)
@@ -0,0 +1,627 @@
+﻿#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 HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+using HeuristicLab.Problems.VehicleRouting;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  [Item("DynPushForwardInsertionCreator", "Creates a randomly initialized VRP solution.")]
+  [StorableClass]
+  public sealed class DynPushForwardInsertionCreator : PotvinCreator, IStochasticOperator {
+    #region IStochasticOperator Members
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    #endregion
+
+    public IValueParameter<DoubleValue> Alpha {
+      get { return (IValueParameter<DoubleValue>)Parameters["Alpha"]; }
+    }
+    public IValueParameter<DoubleValue> AlphaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["AlphaVariance"]; }
+    }
+    public IValueParameter<DoubleValue> Beta {
+      get { return (IValueParameter<DoubleValue>)Parameters["Beta"]; }
+    }
+    public IValueParameter<DoubleValue> BetaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["BetaVariance"]; }
+    }
+    public IValueParameter<DoubleValue> Gamma {
+      get { return (IValueParameter<DoubleValue>)Parameters["Gamma"]; }
+    }
+    public IValueParameter<DoubleValue> GammaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["GammaVariance"]; }
+    }
+
+    [StorableConstructor]
+    private DynPushForwardInsertionCreator(bool deserializing) : base(deserializing) { }
+
+    public DynPushForwardInsertionCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator."));
+      Parameters.Add(new ValueParameter<DoubleValue>("Alpha", "The alpha value.", new DoubleValue(0.7)));
+      Parameters.Add(new ValueParameter<DoubleValue>("AlphaVariance", "The alpha variance.", new DoubleValue(0.5)));
+      Parameters.Add(new ValueParameter<DoubleValue>("Beta", "The beta value.", new DoubleValue(0.1)));
+      Parameters.Add(new ValueParameter<DoubleValue>("BetaVariance", "The beta variance.", new DoubleValue(0.07)));
+      Parameters.Add(new ValueParameter<DoubleValue>("Gamma", "The gamma value.", new DoubleValue(0.2)));
+      Parameters.Add(new ValueParameter<DoubleValue>("GammaVariance", "The gamma variance.", new DoubleValue(0.14)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynPushForwardInsertionCreator(this, cloner);
+    }
+
+    private DynPushForwardInsertionCreator(DynPushForwardInsertionCreator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    // use the Box-Mueller transform in the polar form to generate a N(0,1) random variable out of two uniformly distributed random variables
+    private static double Gauss(IRandom random) {
+      double u = 0.0, v = 0.0, s = 0.0;
+      do {
+        u = (random.NextDouble() * 2) - 1;
+        v = (random.NextDouble() * 2) - 1;
+        s = Math.Sqrt(u * u + v * v);
+      } while (s < Double.Epsilon || s > 1);
+      return u * Math.Sqrt((-2.0 * Math.Log(s)) / s);
+    }
+
+    private static double N(double mu, double sigma, IRandom random) {
+      return mu + (sigma * Gauss(random)); // transform the random variable sampled from N(0,1) to N(mu,sigma)
+    }
+
+    private static double GetDistance(int start, int end, IVRPProblemInstance problemInstance, PotvinEncoding solution) {
+      double distance = 0.0;
+
+      if (problemInstance is DynPDPProblemInstance) {
+        distance = (problemInstance as DynPDPProblemInstance).GetDistance(start, end);
+      }
+      else if (problemInstance.UseDistanceMatrix.Value && problemInstance.DistanceMatrix != null) {
+        distance = problemInstance.DistanceMatrix[start, end];
+      } else {
+        double startX = problemInstance.Coordinates[start, 0];
+        double startY = problemInstance.Coordinates[start, 1];
+
+        double endX = problemInstance.Coordinates[end, 0];
+        double endY = problemInstance.Coordinates[end, 1];
+
+        distance =
+            Math.Sqrt(
+              Math.Pow(startX - endX, 2) +
+              Math.Pow(startY - endY, 2));
+      }
+
+      return distance;
+    }
+
+    private static double GetCosts(int customer, int vehicle, IVRPProblemInstance problemInstance,
+      Dictionary<int, List<int>> vehicles, Dictionary<int, Tour> vehicleTours, List<bool> vehicleUsed, PotvinEncoding solution,
+      double alpha, double beta, double gamma, out bool feasible, out bool existingRoute) {
+      int depotCount = 1;
+      IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance;
+      if (mdp != null) {
+        depotCount = mdp.Depots.Value;
+      }
+
+      feasible = true;
+
+      double distance = GetDistance(vehicle, customer + depotCount - 1, problemInstance, solution);
+      if (vehicleUsed != null) {
+        existingRoute = vehicleUsed[vehicle];
+      } else {
+        existingRoute = true;
+      }
+
+      double dueTime = 0;
+      if (problemInstance is ITimeWindowedProblemInstance) {
+        ITimeWindowedProblemInstance vrptw = problemInstance as ITimeWindowedProblemInstance;
+        dueTime = vrptw.DueTime[customer + depotCount - 1];
+      }
+
+      if (vehicleTours.ContainsKey(vehicle)) {
+        Tour tour = vehicleTours[vehicle];
+
+        IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
+        if (pdp != null && pdp.GetPickupDeliveryLocation(customer) > 0) {
+          solution.InsertPair(tour, customer, pdp.GetPickupDeliveryLocation(customer), problemInstance);
+        } else {
+          tour.Stops.Insert(solution.FindBestInsertionPlace(tour, customer), customer);
+        }
+
+        feasible = problemInstance.TourFeasible(tour, solution);
+
+        tour.Stops.Remove(customer);
+        if (pdp != null && pdp.GetPickupDeliveryLocation(customer) > 0) {
+          tour.Stops.Remove(pdp.GetPickupDeliveryLocation(customer));
+        }
+      }
+      else if (problemInstance is ITimeWindowedProblemInstance) {
+        IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
+        ITimeWindowedProblemInstance vrptw = problemInstance as ITimeWindowedProblemInstance;
+        double time = vrptw.ReadyTime[vehicle];
+        time += distance;
+        if (time > dueTime) {
+          feasible = false;
+        } else {
+          time += vrptw.ServiceTime[customer - 1];
+          if (pdp != null && pdp.GetPickupDeliveryLocation(customer) > 0) {
+            int targetCustomer = pdp.GetPickupDeliveryLocation(customer);
+            time += GetDistance(customer + depotCount - 1, targetCustomer + depotCount - 1, problemInstance, solution);
+            if (time > vrptw.DueTime[targetCustomer + depotCount - 1]) {
+              feasible = false;
+            } 
+
+            time += vrptw.ServiceTime[targetCustomer - 1];
+            time += GetDistance(targetCustomer + depotCount - 1, vehicle, problemInstance, solution);
+
+            if (time > vrptw.DueTime[vehicle]) {
+              feasible = false;
+            } 
+          } else {
+            time += GetDistance(customer + depotCount - 1, vehicle, problemInstance, solution);
+            if (time > vrptw.DueTime[vehicle]) {
+              feasible = false;
+            } 
+          }
+        }
+      }
+
+      if (problemInstance is IHeterogenousCapacitatedProblemInstance) {
+        IHeterogenousCapacitatedProblemInstance cvrp = problemInstance as IHeterogenousCapacitatedProblemInstance;
+        double demand = problemInstance.GetDemand(customer);
+        if (demand > cvrp.Capacity[vehicle])
+          feasible = false;
+      } else if (problemInstance is IHomogenousCapacitatedProblemInstance) {
+        IHomogenousCapacitatedProblemInstance cvrp = problemInstance as IHomogenousCapacitatedProblemInstance;
+        double demand = problemInstance.GetDemand(customer);
+        if (demand > cvrp.Capacity.Value)
+          feasible = false;
+      }
+
+      double x0 = problemInstance.Coordinates[vehicle, 0];
+      double y0 = problemInstance.Coordinates[vehicle, 1];
+      double dist;
+      if (problemInstance.Coordinates[customer + depotCount - 1, 0] < x0)
+        dist = -distance;
+      else
+        dist = distance;
+      double polarAngle = (dist != 0 ? (Math.Asin((problemInstance.Coordinates[customer + depotCount - 1, 1] - y0) / dist) / 360 * dist) : 0);
+
+      if (problemInstance is ITimeWindowedProblemInstance) {
+        ITimeWindowedProblemInstance vrptw = problemInstance as ITimeWindowedProblemInstance;
+
+        if (dueTime == double.MaxValue)
+          dueTime = 0;
+        else {
+          dueTime -= vrptw.ReadyTime[vehicle];
+        }
+      }
+
+      double cost = alpha * distance + // distance 0 <-> City[i]
+                   -beta * dueTime + // latest arrival time
+                  -gamma * polarAngle; // polar angle
+
+      if (vehicleUsed != null) {
+        if (!vehicleUsed[vehicle])
+          cost += problemInstance.FleetUsageFactor.Value;
+      }
+
+      return cost;
+    }
+
+    private static int GetNearestDepot(IVRPProblemInstance problemInstance, List<int> depots, int customer,
+      Dictionary<int, List<int>> vehicles, Dictionary<int, Tour> vehicleTours, List<bool> vehicleUsed, PotvinEncoding solution,
+      double alpha, double beta, double gamma, out double minCost, out bool bound, out bool bestExistingRoute) {
+      int nearest = -1;
+      minCost = double.MaxValue;
+      bestExistingRoute = false;
+
+      bool bestFeasible = false;
+      int feasibleCount = 0;
+      foreach (int depot in depots) {
+        int vehicle = vehicles[depot][0];
+
+        bool existingRoute;
+        bool feasible;
+        double cost = GetCosts(
+          customer, vehicle,
+          problemInstance, vehicles, vehicleTours, vehicleUsed,
+          solution, alpha, beta, gamma, out feasible, out existingRoute);
+
+        if (feasible)
+          feasibleCount++;
+
+        if ((feasible && !bestFeasible) || 
+          (feasible == bestFeasible && existingRoute && !bestExistingRoute) || 
+          (feasible == bestFeasible && existingRoute == bestExistingRoute && cost < minCost)) {
+          minCost = cost;
+          nearest = depot;
+          bestFeasible = feasible;
+          bestExistingRoute = existingRoute;
+        }
+      }
+
+      bound = (feasibleCount == 1);
+
+      return nearest;
+    }
+
+    private static List<int> SortCustomers(IVRPProblemInstance problemInstance, List<int> customers, List<int> depots,
+      Dictionary<int, int> depotAssignment, Dictionary<int, int> customerBinding, 
+      Dictionary<int, List<int>> vehicles, Dictionary<int, Tour> vehicleTours, List<bool> vehicleUsed, PotvinEncoding solution,
+      double alpha, double beta, double gamma) {
+      List<int> sortedCustomers = new List<int>();
+      depotAssignment.Clear();
+      customerBinding.Clear();
+
+      List<bool> boundList = new List<bool>();
+      List<bool> existingRouteList = new List<bool>();
+      List<double> costList = new List<double>();
+
+      for (int i = 0; i < customers.Count; i++) {
+        double cost;
+        bool bound;
+        bool existingRoute;
+        int depot = GetNearestDepot(problemInstance, depots, customers[i], vehicles, vehicleTours, vehicleUsed, solution,
+          alpha, beta, gamma,
+          out cost, out bound, out existingRoute);
+        depotAssignment[customers[i]] = depot;
+        if (bound) {
+          customerBinding.Add(customers[i], depot);
+        }
+
+        int index = 0;
+        while (index < costList.Count &&
+          ((!bound && boundList[index]) || 
+           (bound == boundList[index] && !existingRoute && existingRouteList[index]) || 
+           (bound == boundList[index] && existingRoute == existingRouteList[index] && costList[index] < cost)))
+          index++;
+
+        costList.Insert(index, cost);
+        boundList.Insert(index, bound);
+        existingRouteList.Insert(index, existingRoute);
+        sortedCustomers.Insert(index, customers[i]);
+      }
+
+      return sortedCustomers;
+    }
+
+    private static bool RemoveUnusedDepots(List<int> depots, Dictionary<int, List<int>> vehicles) {
+      List<int> toBeRemoved = new List<int>();
+
+      foreach (int depot in depots) {
+        if (vehicles[depot].Count == 0)
+          toBeRemoved.Add(depot);
+      }
+
+      foreach (int depot in toBeRemoved) {
+        depots.Remove(depot);
+        vehicles.Remove(depot);
+      }
+
+      return toBeRemoved.Count > 0;
+    }
+
+    private static Dictionary<int, Tour> CreateInitialTours(IVRPProblemInstance problemInstance, Dictionary<int, List<int>> vehicles, PotvinEncoding result) {
+      Dictionary<int, Tour> vehicleTours = new Dictionary<int, Tour>();
+      IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
+
+      int currentVehicle;
+
+      for (int i = 1; i <= problemInstance.Cities.Value; i++) {
+        if (pdp != null && pdp.GetPickupDeliveryLocation(i) <= 0) {
+          currentVehicle = -pdp.GetPickupDeliveryLocation(i);
+          foreach (int depot in vehicles.Keys) {
+            if (vehicles[depot].Contains(currentVehicle)) {
+              vehicles[depot].Remove(currentVehicle);
+              vehicles[depot].Insert(0, currentVehicle);
+              break;
+            }
+          }
+
+          Tour tour;
+
+          if (!vehicleTours.ContainsKey(currentVehicle)) {
+            tour = new Tour();
+            result.Tours.Add(tour);
+            vehicleTours[currentVehicle] = tour;
+            result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle;
+          } else {
+            tour = vehicleTours[currentVehicle];
+          }
+
+          tour.Stops.Add(i);
+        }
+      }
+
+      foreach (int vehicle in vehicleTours.Keys) {
+        Tour vehicleTour = vehicleTours[vehicle];
+        List<int> customers = new List<int>(vehicleTour.Stops);
+        vehicleTour.Stops.Clear();
+
+        if (problemInstance is DynPDPProblemInstance &&
+          (problemInstance as DynPDPProblemInstance).CurrentPlan != null) {
+          PotvinEncoding plan = (problemInstance as DynPDPProblemInstance).CurrentPlan;
+          Tour planTour = plan.Tours.Find(t => plan.GetVehicleAssignment(plan.Tours.IndexOf(t)) == vehicle);
+
+          customers.Sort((x, y) => planTour.Stops.IndexOf(x).CompareTo(planTour.Stops.IndexOf(y)));
+          foreach (int customer in customers)
+            vehicleTour.Stops.Add(customer);
+        } else {
+          for (int i = 0; i < customers.Count; i++) {
+            int stop = result.FindBestInsertionPlace(vehicleTour, customers[i]);
+            vehicleTour.Stops.Insert(stop, customers[i]);
+          }
+        }
+      }
+
+      return vehicleTours;
+    }
+
+    public static PotvinEncoding CreateSolution(IVRPProblemInstance problemInstance, IRandom random, List<bool> vehicleUsed, 
+      double alphaValue = 0.7, double betaValue = 0.1, double gammaValue = 0.2,
+      double alphaVariance = 0.5, double betaVariance = 0.07, double gammaVariance = 0.14) {
+      PotvinEncoding result = new PotvinEncoding(problemInstance);
+
+      IPickupAndDeliveryProblemInstance pdp = problemInstance as IPickupAndDeliveryProblemInstance;
+      IMultiDepotProblemInstance mdp = problemInstance as IMultiDepotProblemInstance;
+
+      if (mdp != null) {
+        for (int i = 0; i < result.VehicleAssignment.Length; i++) {
+          result.VehicleAssignment[i] = -1;
+        }
+      }
+
+      double alpha, beta, gamma;
+      lock (random) {
+        alpha = N(alphaValue, Math.Sqrt(alphaVariance), random);
+        beta = N(betaValue, Math.Sqrt(betaVariance), random);
+        gamma = N(gammaValue, Math.Sqrt(gammaVariance), random);
+      }
+
+      #region initialization
+      List<int> unroutedCustomers = new List<int>();
+      for (int i = 1; i <= problemInstance.Cities.Value; i++) {
+        if (pdp == null || (problemInstance.GetDemand(i) >= 0) || (pdp.GetPickupDeliveryLocation(i) == i))
+          unroutedCustomers.Add(i);
+      }
+
+      List<int> depots = new List<int>();
+      if (mdp != null) {
+        for (int i = 0; i < mdp.Depots.Value; i++) {
+          depots.Add(i);
+        }
+      } else {
+        depots.Add(0);
+      }
+
+      Dictionary<int, List<int>> vehicles = new Dictionary<int, List<int>>();
+      foreach (int depot in depots) {
+        vehicles[depot] = new List<int>();
+
+        int vehicleCount = problemInstance.Vehicles.Value;
+        if (mdp != null) {
+          for (int vehicle = 0; vehicle < mdp.VehicleDepotAssignment.Length; vehicle++) {
+            if (mdp.VehicleDepotAssignment[vehicle] == depot) {
+              vehicles[depot].Add(vehicle);
+            }
+          }
+        } else {
+          for (int vehicle = 0; vehicle < vehicleCount; vehicle++) {
+            vehicles[depot].Add(vehicle);
+          }
+        }
+
+        if (vehicleUsed != null) {
+          vehicles[depot].Sort(delegate(int x, int y) {
+            if (vehicleUsed[x] && vehicleUsed[y])
+              return 0;
+            else if (vehicleUsed[x])
+              return -1;
+            else
+              return 1;
+          });
+        }
+      }
+
+      Dictionary<int, Tour> vehicleTours = CreateInitialTours(problemInstance, vehicles, result);
+      RemoveUnusedDepots(depots, vehicles);
+      #endregion
+
+      #region route unrouted
+      if (unroutedCustomers.Count > 0) {
+        Tour tour;
+        int currentDepot;
+        int currentVehicle;
+        Dictionary<int, int> depotAssignment = new Dictionary<int, int>();
+
+        //# sort customers globally - start new tour
+        Dictionary<int, int> customerBinding = new Dictionary<int, int>();
+        unroutedCustomers = SortCustomers(
+          problemInstance, unroutedCustomers, depots, depotAssignment, customerBinding, 
+          vehicles, vehicleTours, vehicleUsed, result,
+          alpha, beta, gamma);
+
+        int currentCustomer = unroutedCustomers[0];
+        currentDepot = depotAssignment[currentCustomer];
+        currentVehicle = vehicles[currentDepot][0];
+        vehicles[currentDepot].RemoveAt(0);
+        RemoveUnusedDepots(depots, vehicles);
+
+        if (!vehicleTours.ContainsKey(currentVehicle)) {
+          tour = new Tour();
+          result.Tours.Add(tour);
+          result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle;
+
+          unroutedCustomers.Remove(currentCustomer);
+          tour.Stops.Add(currentCustomer);
+          if (pdp != null && pdp.GetPickupDeliveryLocation(currentCustomer) != currentCustomer) {
+            tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer));
+          }
+        } else {
+          tour = vehicleTours[currentVehicle];
+        }
+
+        while (unroutedCustomers.Count > 0) {
+          double minimumCost = double.MaxValue;
+          bool bestBoundToRoute = false;
+          int customer = -1;
+          int indexOfMinimumCost = -1;
+          int indexOfMinimumCost2 = -1;
+
+          foreach (int unrouted in unroutedCustomers) {
+            bool boundToRoute = customerBinding.ContainsKey(unrouted) && customerBinding[unrouted] == currentDepot;
+
+            VRPEvaluation eval = problemInstance.EvaluateTour(tour, result);
+            double originalCosts = eval.Quality;
+
+            for (int i = 0; i <= tour.Stops.Count; i++) {
+              tour.Stops.Insert(i, unrouted);
+              eval = problemInstance.EvaluateTour(tour, result);
+              double tourCost = eval.Quality - originalCosts;
+
+              if (pdp != null && pdp.GetPickupDeliveryLocation(unrouted) != unrouted) {
+                for (int j = i + 1; j <= tour.Stops.Count; j++) {
+                  bool feasible;
+                  double cost = tourCost +
+                    problemInstance.GetInsertionCosts(eval, result, pdp.GetPickupDeliveryLocation(unrouted), 0, j, out feasible);
+                  if ((cost < minimumCost || (!bestBoundToRoute && boundToRoute)) && (boundToRoute || !bestBoundToRoute) && feasible) {
+                    customer = unrouted;
+                    minimumCost = cost;
+                    indexOfMinimumCost = i;
+                    indexOfMinimumCost2 = j;
+                    bestBoundToRoute = boundToRoute;
+                  }
+                }
+              } else {
+                double cost = tourCost;
+                bool feasible = problemInstance.Feasible(eval);
+                if ((cost < minimumCost || (!bestBoundToRoute && boundToRoute)) && (boundToRoute || !bestBoundToRoute) && feasible) {
+                  customer = unrouted;
+                  minimumCost = cost;
+                  indexOfMinimumCost = i;
+                  bestBoundToRoute = boundToRoute;
+                }
+              }
+
+              tour.Stops.RemoveAt(i);
+            }
+          }
+
+          if (indexOfMinimumCost == -1 && vehicles.Count == 0) {
+            indexOfMinimumCost = tour.Stops.Count;
+            indexOfMinimumCost2 = tour.Stops.Count + 1;
+            customer = unroutedCustomers[0];
+          }
+
+          // insert customer if found
+          if (indexOfMinimumCost != -1) {
+            tour.Stops.Insert(indexOfMinimumCost, customer);
+            if (pdp != null && pdp.GetPickupDeliveryLocation(customer) != customer) {
+              tour.Stops.Insert(indexOfMinimumCost2, pdp.GetPickupDeliveryLocation(customer));
+            }
+            unroutedCustomers.Remove(customer);
+          } else { // no feasible customer found
+            //# sort customers globally - start new tour
+            unroutedCustomers = SortCustomers(
+              problemInstance, unroutedCustomers, depots, depotAssignment, customerBinding,
+              vehicles, vehicleTours, vehicleUsed, result,
+              alpha, beta, gamma);
+            
+            currentCustomer = unroutedCustomers[0];
+            currentDepot = depotAssignment[currentCustomer];
+            currentVehicle = vehicles[currentDepot][0];
+            vehicles[currentDepot].RemoveAt(0);
+            RemoveUnusedDepots(depots, vehicles);
+
+            if (!vehicleTours.ContainsKey(currentVehicle)) {
+              tour = new Tour();
+              result.Tours.Add(tour);
+              result.VehicleAssignment[result.Tours.Count - 1] = currentVehicle;
+
+              unroutedCustomers.Remove(currentCustomer);
+              tour.Stops.Add(currentCustomer);
+              if (pdp != null && pdp.GetPickupDeliveryLocation(currentCustomer) != currentCustomer) {
+                tour.Stops.Add(pdp.GetPickupDeliveryLocation(currentCustomer));
+              }
+            } else {
+              tour = vehicleTours[currentVehicle];
+            }
+          }
+        }
+      }
+      #endregion
+
+      #region assign vehicles
+      if (mdp != null) {
+        List<int> availableVehicles = new List<int>();
+        for (int i = 0; i < mdp.Vehicles.Value; i++)
+          availableVehicles.Add(i);
+
+        for (int i = 0; i < result.VehicleAssignment.Length; i++) {
+          if (result.VehicleAssignment[i] != -1)
+            availableVehicles.Remove(result.VehicleAssignment[i]);
+        }
+
+        for (int i = 0; i < result.VehicleAssignment.Length; i++) {
+          if (result.VehicleAssignment[i] == -1) {
+            result.VehicleAssignment[i] = availableVehicles[0];
+            availableVehicles.RemoveAt(0);
+          }
+        }
+      }
+      #endregion
+
+      return result;
+    }
+
+    public override IOperation Apply() {
+      List<bool> vehicleUsed = null;
+      
+      DynPDPProblemInstance instance = ProblemInstance as DynPDPProblemInstance;
+      if(instance != null) {
+        vehicleUsed = new List<bool>();
+        for (int i = 0; i < instance.VehicleUsed.Length; i++) {
+          vehicleUsed.Add(instance.VehicleUsed[i]);
+        }
+      }
+
+      VRPToursParameter.ActualValue = CreateSolution(ProblemInstance, RandomParameter.ActualValue, vehicleUsed,
+        Alpha.Value.Value, Beta.Value.Value, Gamma.Value.Value,
+        AlphaVariance.Value.Value, BetaVariance.Value.Value, GammaVariance.Value.Value);
+
+      return base.Apply();
+    }
+  }
+}
+
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/LinearPriorityDispatchingMetaOptEvaluator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/LinearPriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/LinearPriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
@@ -0,0 +1,45 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Common;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using System.Diagnostics;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  [Item("LinearPriorityDispatchingMetaOptEvaluator", "Metaoptimization of the priority dispatching parameters for the PDP simulation.")]
+  [StorableClass]
+  public class LinearPriorityDispatchingMetaOptEvaluator : PriorityDispatchingMetaOptEvaluator {
+    public IValueLookupParameter<DoubleArray> VectorParameter {
+      get { return (IValueLookupParameter<DoubleArray>)Parameters["Vector"]; }
+    }
+
+    public LinearPriorityDispatchingMetaOptEvaluator() {
+      Parameters.Add(new ValueLookupParameter<DoubleArray>("Vector", "The priority dispatching parameters."));
+    }
+
+    [StorableConstructor]
+    protected LinearPriorityDispatchingMetaOptEvaluator(bool deserializing) : base(deserializing) { }
+    protected LinearPriorityDispatchingMetaOptEvaluator(LinearPriorityDispatchingMetaOptEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearPriorityDispatchingMetaOptEvaluator(this, cloner);
+    }
+
+    protected override void Parameterize(PriorityDispatching dispatching) {
+      DoubleArray vector = VectorParameter.ActualValue;
+
+      LinearPriorityDispatching linearDispatching = dispatching as LinearPriorityDispatching;
+      linearDispatching.WeightsParameter.Value = new RealVector(vector.ToArray());
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/PriorityDispatchingMetaOptEvaluator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/PriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/PriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
@@ -0,0 +1,109 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Common;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using System.Diagnostics;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  [Item("PriorityDispatchingMetaOptEvaluator", "Metaoptimization of the priority dispatching parameters for the PDP simulation.")]
+  [StorableClass]
+  public abstract class PriorityDispatchingMetaOptEvaluator : SingleSuccessorOperator, ISingleObjectiveEvaluator {
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public IValueParameter<ItemList<PickupDeliverySimulation>> SimulationParameter {
+      get { return (IValueParameter<ItemList<PickupDeliverySimulation>>)Parameters["Simulation"]; }
+    }
+
+    public IValueParameter<IntValue> RepetitionsParameter {
+      get { return (IValueParameter<IntValue>)Parameters["Repetitions"]; }
+    }
+
+    public PriorityDispatchingMetaOptEvaluator() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "Result of the evaluation of a solution."));
+      Parameters.Add(new ValueParameter<ItemList<PickupDeliverySimulation>>("Simulation", "The PDP simulation"));
+      Parameters.Add(new ValueParameter<IntValue>("Repetitions", "The number of repetitions", new IntValue(1)));
+    }
+
+    [StorableConstructor]
+    protected PriorityDispatchingMetaOptEvaluator(bool deserializing) : base(deserializing) { }
+    protected PriorityDispatchingMetaOptEvaluator(PriorityDispatchingMetaOptEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    protected abstract void Parameterize(PriorityDispatching dispatching);
+
+    public override IOperation Apply() {
+      double quality = 0;
+
+      List<PickupDeliverySimulation> simulations = new List<PickupDeliverySimulation>();
+      foreach (var originalSimulation in SimulationParameter.Value) {
+        PickupDeliverySimulation simulation = originalSimulation.Clone() as PickupDeliverySimulation;
+        PriorityDispatching dispatching = simulation.OptimizationParameter.Value as PriorityDispatching;
+        Parameterize(dispatching);
+
+        simulations.Add(simulation);
+      }
+
+      int repetitions = 0;
+      object locker = new object();
+      var options = new ParallelOptions();
+      //options.MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount - 1, 1);
+      Parallel.ForEach<PickupDeliverySimulation>(simulations, options, simulation => {
+        int index = simulations.IndexOf(simulation);
+        int executions = 0;
+
+        using (EventWaitHandle waitHandle = new EventWaitHandle(false, EventResetMode.ManualReset)) {
+          EventHandler handler = new EventHandler(delegate(object o, EventArgs e) {
+            waitHandle.Set();
+          });
+
+          while (executions < RepetitionsParameter.Value.Value) {
+            waitHandle.Reset();
+
+            simulation.Prepared += handler;
+            simulation.Prepare(true);
+            waitHandle.WaitOne();
+            simulation.Prepared -= handler;
+
+            waitHandle.Reset();
+
+            simulation.Stopped += handler;
+            simulation.Start();
+            waitHandle.WaitOne();
+            simulation.Stopped -= handler;
+
+            if (!simulation.Results.ContainsKey("Finished")) {
+              throw new Exception("Simulation did not finish");
+            }
+            executions++;
+
+            double leadTime = (simulation.Results["LeadTime"].Value as DoubleValue).Value;
+            double tardiness = (simulation.Results["TotalTardinessPenalty"].Value as DoubleValue).Value;
+
+            lock (locker) {
+              double runQuality = leadTime + tardiness;
+
+              quality += runQuality;
+              repetitions++;
+            }
+          }
+        }
+      });
+
+      QualityParameter.ActualValue = new DoubleValue(quality / (double)repetitions);
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/TreePriorityDispatchingMetaOptEvaluator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/TreePriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Operators/TreePriorityDispatchingMetaOptEvaluator.cs	(revision 16099)
@@ -0,0 +1,54 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Common;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using System.Diagnostics;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.PDPSimulation.Operators {
+  [Item("TreePriorityDispatchingMetaOptEvaluator", "Metaoptimization of the priority dispatching parameters for the PDP simulation.")]
+  [StorableClass]
+  public class TreePriorityDispatchingMetaOptEvaluator : PriorityDispatchingMetaOptEvaluator {
+    public IValueLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (IValueLookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+
+    public IValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (IValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters["SymbolicExpressionTreeInterpreter"]; }
+    }
+
+    public TreePriorityDispatchingMetaOptEvaluator() {
+      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic data analysis solution encoded as a symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>("SymbolicExpressionTreeInterpreter", "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.")); 
+    }
+
+    [StorableConstructor]
+    protected TreePriorityDispatchingMetaOptEvaluator(bool deserializing) : base(deserializing) { }
+    protected TreePriorityDispatchingMetaOptEvaluator(TreePriorityDispatchingMetaOptEvaluator original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TreePriorityDispatchingMetaOptEvaluator(this, cloner);
+    }
+
+    protected override void Parameterize(PriorityDispatching dispatching) {
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+
+      TreePriorityDispatching treeDispatching = dispatching as TreePriorityDispatching;
+      treeDispatching.SymbolicExpressionTreeParameter.Value = tree;
+      treeDispatching.SymbolicDataAnalysisTreeInterpreterParameter.Value = interpreter;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDPOptimization.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDPOptimization.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDPOptimization.cs	(revision 16099)
@@ -0,0 +1,350 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using System.Threading;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading.Tasks;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation {
+  [StorableClass]
+  public abstract class DynamicPDPOptimization : PickupDeliveryOptimization {
+    public ValueParameter<BoolValue> OnlyOptimizedIfRequiredParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["OnlyOptimizedIfRequired"]; }
+    }
+
+    public DynamicPDPOptimization(): base() {
+      optimizationFinshed = true;
+      Parameters.Add(new ValueParameter<BoolValue>("OnlyOptimizedIfRequired", "Only optimize if new information is revealed.", new BoolValue(true)));
+    }
+    [StorableConstructor]
+    protected DynamicPDPOptimization(bool deserializing) : base(deserializing) {
+    }
+    protected DynamicPDPOptimization(DynamicPDPOptimization original, Cloner cloner)
+      : base(original, cloner) {
+        instance = cloner.Clone<DynamicPDProblemInstance>(original.instance);
+        lastUpdateTime = original.lastUpdateTime;
+        optimizationFinshed = original.optimizationFinshed;
+    }
+
+    [Storable]
+    private DynamicPDProblemInstance instance;
+
+    protected DynamicPDProblemInstance Instance {
+      get { return instance; }
+    }
+
+    [Storable]
+    private double lastUpdateTime;
+
+    [Storable]
+    private bool optimizationFinshed;
+
+    public override void SetScenario(PickupDeliveryScenario scenario) {
+      base.SetScenario(scenario);
+      instance = new DynamicPDProblemInstance(scenario, GetResults());
+    }
+
+    public override void SetWaitingStrategy(WaitingStrategy waitingStrategy) {
+      base.SetWaitingStrategy(waitingStrategy);
+      if (instance != null) {
+        foreach (IVRPProblemInstance staticInstance in instance.StaticInstances)
+          (staticInstance as DynPDPProblemInstance).WaitingStrategy = waitingStrategy;
+      }
+    }
+
+    public override void Prepare() {
+      lastUpdateTime = 0;
+      optimizationFinshed = true;
+      instance = new DynamicPDProblemInstance(scenario, GetResults());
+      foreach (IVRPProblemInstance staticInstance in instance.StaticInstances)
+        (staticInstance as DynPDPProblemInstance).WaitingStrategy = waitingStrategy;
+      base.Prepare();
+    }
+
+    protected virtual void PrepareInstance(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
+      instance.InitializeInstance(changeInformation.CreatedVehicles, changeInformation.CreatedOrders);
+    }
+
+    protected virtual void PerformPlan(IVRPEncoding solution) {
+      lock (actionLocker) {
+        instance.SetCurrentPlan(PotvinEncoding.ConvertFrom(solution, instance.StaticInstance));
+        DynPDPEvaluation eval = instance.StaticInstance.Evaluate(solution) as DynPDPEvaluation;
+
+        List<int> vehicles = new List<int>();
+        for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++)
+          vehicles.Add(i);
+
+        int tourIdx = 0;
+        foreach (Tour tour in solution.GetTours()) {
+          List<double> waitingTimes = DynPDPEvaluator.GetWaitingTimes(instance.StaticInstance as DynPDPProblemInstance, tour, solution);
+
+          int vehicleIdx = solution.GetVehicleAssignment(
+            solution.GetTourIndex(tour));
+          vehicles.Remove(vehicleIdx);
+          Guid vehicleId = instance.GetVehicle(vehicleIdx);
+          Vehicle vehicle = GetVehicle(vehicleId);
+
+          int stopIdx = 0;
+          foreach (int stop in tour.Stops) {
+            double coordX = instance.StaticInstance.GetCoordinates(stop)[0];
+            double coordY = instance.StaticInstance.GetCoordinates(stop)[1];
+            VehicleAction vehicleAction;
+
+            Guid orderId = instance.GetOrder(stop);
+            Order order = GetOrder(orderId);
+            order.AssignedVehicle = vehicleId;
+
+            if (instance.StaticInstance.GetDemand(stop) >= 0) {
+              vehicleAction = VehicleAction.Pickup;
+            } else {
+              vehicleAction = VehicleAction.Deliver;
+            }
+
+            if (instance.StaticInstance.GetDemand(stop) != 0) {
+              double waitingTime = waitingTimes[stopIdx];
+
+              PDAction action = new WaitAction(vehicleId, waitingTime);
+              if (stopIdx == 0) {
+                SetAction(action);
+              } else {
+                AppendAction(action);
+              }
+
+              action = new MoveVehicleAction(
+                vehicleId,
+                coordX,
+                coordY,
+                vehicleAction,
+                order, 
+                scenario.AllowDiversion, 
+                scenario.DistanceMeasure);
+
+              AppendAction(action);                            
+            }
+
+            stopIdx++;
+          }
+
+          tourIdx++;
+        }
+
+        foreach (int vehicleIdx in vehicles) {
+          Guid vehicleId = instance.GetVehicle(vehicleIdx);
+          Vehicle vehicle = GetVehicle(vehicleId);
+
+          double posX, posY;
+          lock (vehicle) {
+            if (!scenario.AllowDiversion) {
+              posX = vehicle.TargetPositionX;
+              posY = vehicle.TargetPositionY;
+            } else {
+              posX = vehicle.PositionX;
+              posY = vehicle.PositionY;
+            }
+          }
+
+          SetAction(new WaitAction(vehicleId, 0));
+        }
+      }
+    }
+
+    private void UpdateInstance(ChangeInformation changeInformation) {
+      if (!instance.Initialized) {
+        PrepareInstance(instance, changeInformation);
+      } else {
+        foreach (Vehicle vehicle in changeInformation.CreatedVehicles) {
+          lock (vehicle) {
+            instance.AddVehicle(vehicle);
+          }
+        }
+
+        foreach (Order order in changeInformation.CreatedOrders)
+          instance.AddOrder(order);
+
+        foreach (Vehicle vehicle in changeInformation.ChangedVehicles) {
+          lock (vehicle) {
+            instance.UpdateVehicle(vehicle, scenario.AllowDiversion);
+          }
+        }
+
+        foreach (Order order in changeInformation.ChangedOrders)
+          instance.UpdateOrder(order, scenario.AllowDiversion);
+      }
+
+      double time = GetSimulationTime();
+      double delta = time - lastUpdateTime;
+      lastUpdateTime = time;
+
+      instance.UpdateTime(delta);
+    }
+
+    protected virtual void BeginInstanceUpdate(DynamicPDProblemInstance instance) {
+    }
+
+    protected virtual void EndInstanceUpdate(DynamicPDProblemInstance instance) {
+    }
+
+    protected virtual bool OptimizationRequired(ChangeInformation changeInformation) {
+      return (!OnlyOptimizedIfRequiredParameter.Value.Value && Instance.StaticInstance != null && Instance.StaticInstance.Cities.Value > 0) || 
+        changeInformation.CreatedOrders.Count > 0 || changeInformation.InvalidActions;
+    }
+
+    protected virtual void StartOptimization() {
+    }
+
+    protected virtual void EndOptimization() {
+      SignalWaitHandle();
+      running = false;
+    }
+
+    protected abstract bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation);
+
+    protected object myLock = new object();
+
+    public override bool OptimizationRequired() {
+      lock (myLock) {
+        if (optimizationFinshed) {
+          bool optimize = OptimizationRequired(GetChangeInformation(GetChanges(false)));
+          if(optimize)
+            optimizationFinshed = false;
+          
+          return optimize;
+        } else {
+          return true;
+        }
+      }
+    }
+
+    private void RelocateToDepot(Guid vehicleId, double simulationTime, bool finish) {
+      Vehicle vehicle = GetVehicle(vehicleId);
+      double posX, posY;
+      lock (vehicle) {
+        posX = vehicle.TargetPositionX;
+        posY = vehicle.TargetPositionY;
+      }
+
+      bool moveToDepot = finish;
+      if (!finish) {
+        double length = scenario.DistanceMeasure.GetDistance(posX, posY, vehicle.DepotX, vehicle.DepotY);
+
+        moveToDepot = (simulationTime + length >= vehicle.DueTime);
+      }
+
+      if (moveToDepot) {
+        bool moved = false;
+        PDAction action = GetAction(vehicle);
+        while (action != null && action.Successor != null) {
+          action = action.Successor;
+        }
+
+        moved = action != null && action is MoveVehicleAction &&
+          (action as MoveVehicleAction).TargetX == vehicle.DepotX &&
+          (action as MoveVehicleAction).TargetY == vehicle.DepotY;
+
+        if (!moved)
+          AppendAction(new MoveVehicleAction(vehicleId, vehicle.DepotX, vehicle.DepotY, VehicleAction.Park, null,
+                scenario.AllowDiversion, scenario.DistanceMeasure));
+      }
+    }
+
+    protected virtual void RelocateVehicles(double simulationTime, bool finish) {
+      lock (actionLocker) {
+        for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++) {
+          Guid vehicleId = instance.GetVehicle(i);
+          RelocateToDepot(vehicleId, simulationTime, finish);
+        }
+      }
+    }
+
+    public override void RelocateVehicles() {
+      if (scenario.RelocateBackToDepot) {
+        double simulationTime = GetSimulationTime() + GetTimeStep();
+        RelocateVehicles(simulationTime, false);
+      }
+    }
+
+    int index = 0;
+    protected override void Optimize(CancellationToken token) {
+      bool finish = false;
+      bool optimize = false;
+      bool simulationFinished = false;
+
+      ChangeInformation changeInformation;
+
+      StartOptimization();
+
+      while (!token.IsCancellationRequested && !finish) {
+        WaitForSimulation();
+        lock (myLock) {
+          List<PDChange> changes = GetChanges(true);
+          changeInformation = GetChangeInformation(changes);
+
+          BeginInstanceUpdate(instance);
+          UpdateInstance(changeInformation);          
+          EndInstanceUpdate(instance);
+
+          optimize = OptimizationRequired(changeInformation);
+          optimizationFinshed = !optimize;
+        }
+
+        double simulationTime = GetSimulationTime();
+
+        if (changeInformation.SimulationFinished)
+          simulationFinished = true;
+
+        if (optimize) {
+          optimizationFinshed = PerformOptimization(instance, changeInformation);
+
+          /*VehicleRoutingProblem problem = new VehicleRoutingProblem();
+            problem.ProblemInstance = instance.StaticInstance;
+            index++;
+            HeuristicLab.Persistence.Default.Xml.XmlGenerator.Serialize(problem, @"C:\Users\svonolfen\Desktop\tests\i_" + index + ".hl");*/
+        }
+        
+        finish = simulationFinished && optimizationFinshed;
+
+        if(scenario.RelocateBackToDepot)
+          RelocateVehicles(simulationTime + GetTimeStep(), finish);
+
+        if (!finish)
+          SignalWaitHandle();
+      }
+
+      EndOptimization();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDProblemInstance.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDProblemInstance.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/DynamicPDProblemInstance.cs	(revision 16099)
@@ -0,0 +1,504 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Data;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("DynamicPDProblemInstance", "A dynamic PD instance.")]
+  [StorableClass]
+  public class DynamicPDProblemInstance: Item {
+    [Storable]
+    private List<DynPDPProblemInstance> instances;
+
+    [Storable]
+    private HashSet<PotvinEncoding> solutions;
+
+    [Storable]
+    private List<Item> tabuAttributes;
+
+    [Storable]
+    private Dictionary<int, Guid> vehicleAssignment;
+
+    [Storable]
+    private Dictionary<int, Guid> orderAssignment;
+
+    [Storable]
+    private double timeDelta;
+
+    [Storable]
+    private bool initialized;
+
+    public bool Initialized {
+      get { return initialized; }
+    }
+
+    public List<IVRPProblemInstance> StaticInstances {
+      get {
+        List<IVRPProblemInstance> result = new List<IVRPProblemInstance>();
+
+        foreach (DynPDPProblemInstance instance in instances)
+          result.Add(instance);
+
+        return result;
+      }
+    }
+
+    public IVRPProblemInstance StaticInstance {
+      get {
+        return instances[0];
+      }
+    }
+
+    public HashSet<PotvinEncoding> Solutions {
+      get { return solutions;  }
+    }
+
+    public List<Item> TabuAttributes {
+      get { return tabuAttributes; }
+    }
+
+    public void SetInstanceCount(int count) {
+      if (count > 0) {
+        if (instances.Count > count)
+          instances.RemoveRange(0, instances.Count - count);
+        else
+          while(instances.Count < count)
+            instances.Add(instances[0].ShallowClone());
+      }
+    }
+
+    public DynamicPDProblemInstance(PickupDeliveryScenario scenario, ResultCollection results): base() {
+      vehicleAssignment = new Dictionary<int, Guid>();
+      orderAssignment = new Dictionary<int, Guid>();
+      solutions = new HashSet<PotvinEncoding>();
+      tabuAttributes = new List<Item>();
+      timeDelta = 0;
+      initialized = false;
+
+      instances = new List<DynPDPProblemInstance>();
+      instances.Add(new DynPDPProblemInstance(scenario, results));
+    }
+
+    [StorableConstructor]
+    private DynamicPDProblemInstance(bool deserializing) : base(deserializing) {
+    }
+    private DynamicPDProblemInstance(DynamicPDProblemInstance original, Cloner cloner)
+      : base(original, cloner) {
+      instances = new List<DynPDPProblemInstance>();
+      foreach (DynPDPProblemInstance instance in original.instances)
+        instances.Add(cloner.Clone<DynPDPProblemInstance>(instance));
+
+      vehicleAssignment = new Dictionary<int, Guid>();
+      foreach (int key in original.vehicleAssignment.Keys)
+        vehicleAssignment.Add(key, original.vehicleAssignment[key]);
+
+      orderAssignment = new Dictionary<int, Guid>();
+      foreach (int key in original.orderAssignment.Keys)
+        orderAssignment.Add(key, original.orderAssignment[key]);
+
+      solutions = new HashSet<PotvinEncoding>();
+      foreach (PotvinEncoding solution in original.solutions)
+        solutions.Add(cloner.Clone<PotvinEncoding>(solution));
+      
+      tabuAttributes = new List<Item>();
+      foreach (Item tabuAttribute in original.tabuAttributes)
+        tabuAttributes.Add(cloner.Clone<Item>(tabuAttribute));
+
+      timeDelta = original.timeDelta;
+      initialized = original.initialized;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynamicPDProblemInstance(this, cloner);
+    }
+
+    public void SetCurrentPlan(PotvinEncoding plan) {
+      foreach (DynPDPProblemInstance instance in instances) {
+        if (instance.CurrentPlan != null)
+          solutions.Remove(instance.CurrentPlan);
+
+        instance.CurrentPlan = PotvinEncoding.ConvertFrom(plan, instance);
+        solutions.Add(instance.CurrentPlan);
+      }
+    }
+
+    public Guid GetOrder(int stop) {
+      return orderAssignment[stop - 1];
+    }
+
+    public List<int> GetStops(Guid order) {
+      return (from a in orderAssignment where a.Value == order select a.Key).OrderBy(s => s).ToList();
+    }
+
+    public Guid GetVehicle(int index) {
+      return vehicleAssignment[index];
+    }
+
+    public void UpdateTime(double delta) {
+      foreach (DynPDPProblemInstance instance in instances) {
+        for (int i = 0; i < instance.DueTime.Length; i++) {
+          instance.DueTime[i] = Math.Max(0, instance.DueTime[i] - delta);
+          instance.ReadyTime[i] = Math.Max(0, instance.ReadyTime[i] - delta);
+        }
+      }
+
+      timeDelta += delta;
+    }
+
+    public void AddVehicle(Vehicle vehicle) {
+      throw new NotImplementedException();
+    }
+
+    private void AddOrder(DynPDPProblemInstance instance, Order order, ref int customerIdx, ref int depotIdx) {
+      orderAssignment[customerIdx] = order.Id;
+
+      instance.Demand[customerIdx] = order.Demand;
+      instance.PickupDeliveryLocation[customerIdx] = customerIdx + (order.ServiceRequest ? 1 : 2);
+      instance.ServiceTime[customerIdx] = order.PickupServiceTime;
+      instance.ReadyTime[customerIdx + depotIdx] = Math.Max(0, order.PickupReadyTime - timeDelta);
+      instance.DueTime[customerIdx + depotIdx] = Math.Max(0, order.PickupDueTime - timeDelta);
+      instance.Coordinates[customerIdx + depotIdx, 0] = order.PickupXCoord;
+      instance.Coordinates[customerIdx + depotIdx, 1] = order.PickupYCoord;
+      customerIdx++;
+
+      if (!order.ServiceRequest) {
+        orderAssignment[customerIdx] = order.Id;
+
+        instance.Demand[customerIdx] = -order.Demand;
+        instance.PickupDeliveryLocation[customerIdx] = customerIdx;
+        instance.ServiceTime[customerIdx] = order.DeliveryServiceTime;
+        instance.ReadyTime[customerIdx + depotIdx] = Math.Max(0, order.DeliveryReadyTime - timeDelta);
+        instance.DueTime[customerIdx + depotIdx] = Math.Max(0, order.DeliveryDueTime - timeDelta);
+        instance.Coordinates[customerIdx + depotIdx, 0] = order.DeliveryXCoord;
+        instance.Coordinates[customerIdx + depotIdx, 1] = order.DeliveryYCoord;
+        customerIdx++;
+      }
+
+      foreach (PotvinEncoding solution in solutions) {
+        if (!order.ServiceRequest && !solution.Unrouted.Contains(customerIdx - 1))
+          solution.Unrouted.Add(customerIdx - 1);
+
+        if (!solution.Unrouted.Contains(customerIdx))
+          solution.Unrouted.Add(customerIdx);
+      }
+    }
+
+    public void AddOrder(Order order) {
+      foreach (DynPDPProblemInstance instance in instances) {
+        int customerIdx = instance.Demand.Length;
+        int depotIdx = instance.Vehicles.Value;
+
+        int added = order.ServiceRequest ? 1 : 2;
+        (instance.Coordinates as IStringConvertibleMatrix).Rows += added;
+        (instance.ReadyTime as IStringConvertibleArray).Length += added;
+        (instance.DueTime as IStringConvertibleArray).Length += added;
+        (instance.Demand as IStringConvertibleArray).Length += added;
+        (instance.ServiceTime as IStringConvertibleArray).Length += added;
+        (instance.PickupDeliveryLocation as IStringConvertibleArray).Length += added;
+
+        AddOrder(instance, order, ref customerIdx, ref depotIdx);
+
+        instance.ResetDistanceMatrix();
+      }
+    }
+
+    public void UpdateVehicle(Vehicle vehicle, bool diversionAllowed) {
+      bool last = false;
+      for (int i = 0; i < instances.Count; i++) {
+        DynPDPProblemInstance instance = instances[i];
+        last = (i == instances.Count - 1);
+        int vehicleIdx = vehicleAssignment.First(kvp => kvp.Value == vehicle.Id).Key;
+
+        if (!diversionAllowed && vehicle.VehicleState == VehicleState.Moving)
+          instance.VehicleStates[vehicleIdx] = VehicleState.Waiting;
+        else
+          instance.VehicleStates[vehicleIdx] = vehicle.VehicleState;
+
+        if (diversionAllowed) {
+          instance.Coordinates[vehicleIdx, 0] = vehicle.PositionX;
+          instance.Coordinates[vehicleIdx, 1] = vehicle.PositionY;
+
+          instance.Capacity[vehicleIdx] = vehicle.Capacity;
+
+          instance.ResetDistanceMatrix();
+          if (vehicle.Distance > 0)
+            instance.VehicleUsed[vehicleIdx] = true;
+        } else {
+          var found = orderAssignment.Where(kvp => kvp.Value == vehicle.CurrentOrder).ToList();
+          if (found.Count() > 0) {
+            instance.Coordinates[vehicleIdx, 0] = vehicle.TargetPositionX;
+            instance.Coordinates[vehicleIdx, 1] = vehicle.TargetPositionY;
+
+            int target = -1, source = -1;
+            if (found.Count == 2 &&
+               (vehicle.CurrentAction == VehicleAction.Pickup || vehicle.CurrentAction == VehicleAction.Deliver)) {
+              if (instance.Demand[found[0].Key] >= 0) {
+                source = found[0].Key;
+                target = found[1].Key;
+              } else {
+                target = found[0].Key;
+                source = found[1].Key;
+              }
+
+              int vehicleId = vehicleAssignment.First(
+               kvp => kvp.Value == vehicle.Id).Key;
+              instance.PickupDeliveryLocation[target] = -vehicleId;
+            } else if (found.Count == 1 &&
+              (vehicle.CurrentAction == VehicleAction.Deliver)) {
+              source = found[0].Key;
+            }
+
+            if (source >= 0) {
+              if(last)
+                RemoveCustomer(source, vehicleIdx, diversionAllowed);
+              instance.ResetDistanceMatrix();
+            }
+
+            instance.VehicleUsed[vehicleIdx] = true;
+          }
+        }
+
+        instance.ReadyTime[vehicleIdx] = Math.Max(0, vehicle.ReadyTime - timeDelta);
+        vehicleAssignment[vehicleIdx] = vehicle.Id;
+      }
+    }
+
+    private void RemoveCustomer(int customer, int vehicle, bool diversionAllowed) {
+      foreach (DynPDPProblemInstance instance in instances) {
+        if (!diversionAllowed) {
+          instance.Capacity[vehicle] -= instance.Demand[customer];
+        }
+
+        int customers = instance.Cities.Value;
+        int depots = instance.Vehicles.Value;
+
+        for (int i = customer; i < customers - 1; i++) {
+          instance.Demand[i] = instance.Demand[i + 1];
+          instance.ServiceTime[i] = instance.ServiceTime[i + 1];
+          instance.PickupDeliveryLocation[i] = instance.PickupDeliveryLocation[i + 1];
+
+          int index = i + depots;
+          instance.ReadyTime[index] = instance.ReadyTime[index + 1];
+          instance.DueTime[index] = instance.DueTime[index + 1];
+          instance.Coordinates[index, 0] = instance.Coordinates[index + 1, 0];
+          instance.Coordinates[index, 1] = instance.Coordinates[index + 1, 1];
+        }
+
+        for (int i = 0; i < customers; i++) {
+          if (instance.PickupDeliveryLocation[i] > customer)
+            instance.PickupDeliveryLocation[i] -= 1;
+        }
+
+        (instance.Coordinates as IStringConvertibleMatrix).Rows -= 1;
+        (instance.ReadyTime as IStringConvertibleArray).Length -= 1;
+        (instance.DueTime as IStringConvertibleArray).Length -= 1;
+        (instance.Demand as IStringConvertibleArray).Length -= 1;
+        (instance.ServiceTime as IStringConvertibleArray).Length -= 1;
+        (instance.PickupDeliveryLocation as IStringConvertibleArray).Length -= 1;
+      }
+
+      foreach (PotvinEncoding solution in solutions) {
+        int i;
+        foreach (Tour tour in solution.Tours) {
+          i = 0;
+          while (i < tour.Stops.Count) {
+            if (tour.Stops[i] > (customer + 1)) {
+              tour.Stops[i] = tour.Stops[i] - 1;
+              i++;
+            } else if (tour.Stops[i] < (customer + 1)) {
+              i++;
+            } else {
+              tour.Stops.RemoveAt(i);
+            }
+          }
+        }
+
+        solution.Repair();
+
+        i = 0;
+        while (i < solution.Unrouted.Count) {
+          if (solution.Unrouted[i] > (customer + 1)) {
+            solution.Unrouted[i] = solution.Unrouted[i] - 1;
+            i++;
+          } else if (solution.Unrouted[i] < (customer + 1)) {
+            i++;
+          } else {
+            solution.Unrouted.RemoveAt(i);
+          }
+        }
+      }
+
+      Dictionary<int, Guid> newOrderAssignment = new Dictionary<int, Guid>();
+      foreach (int assigned in orderAssignment.Keys) {
+        if (assigned > customer)
+          newOrderAssignment[assigned - 1] = orderAssignment[assigned];
+        else if (assigned != customer)
+          newOrderAssignment[assigned] = orderAssignment[assigned];
+      }
+      orderAssignment = newOrderAssignment;
+    }
+
+    public void UpdateOrder(Order order, bool diversionAllowed) {
+      bool last = false;
+      for(int i = 0; i < instances.Count; i++) {
+        DynPDPProblemInstance instance = instances[i];
+        last = (i == instances.Count - 1);
+        var customers = orderAssignment.Where(
+          kvp => kvp.Value == order.Id).ToList();
+        int depots = instance.Vehicles.Value;
+        int vehicle = vehicleAssignment.First(
+              kvp => kvp.Value == order.Vehicle).Key;
+
+        int source = -1;
+        int target = -1;
+
+        if (order.OrderState == OrderState.PickingUp || order.OrderState == OrderState.PickedUp) {
+          if (!order.ServiceRequest && customers.Count == 2) {
+            if (instance.Demand[customers[0].Key] >= 0) {
+              source = customers[0].Key;
+              target = customers[1].Key;
+            } else {
+              source = customers[1].Key;
+              target = customers[0].Key;
+            }
+
+            instance.PickupDeliveryLocation[target] = -vehicle;
+            if (last)
+              RemoveCustomer(source, vehicle, diversionAllowed);
+            instance.ResetDistanceMatrix();
+          } else if (order.ServiceRequest && customers.Count == 1) {
+            target = customers[0].Key;
+
+            if (last)
+              RemoveCustomer(target, vehicle, diversionAllowed);
+            instance.ResetDistanceMatrix();
+          }
+        } else if (order.OrderState == OrderState.Delivering || order.OrderState == OrderState.Delivered) {
+          if (customers.Count == 1) {
+            target = customers[0].Key;
+
+            if (last)
+              RemoveCustomer(target, vehicle, diversionAllowed);
+            instance.ResetDistanceMatrix();
+          } else if (customers.Count == 2) {
+            if (instance.Demand[customers[0].Key] >= 0) {
+              source = customers[0].Key;
+              target = customers[1].Key;
+            } else {
+              source = customers[1].Key;
+              target = customers[0].Key;
+            }
+
+            if (last)
+              RemoveCustomer(source, vehicle, diversionAllowed);
+            if (last)
+              RemoveCustomer(target - 1, vehicle, diversionAllowed);
+            instance.ResetDistanceMatrix();
+          }
+        }
+      }
+    }
+
+    public void InitializeInstance(List<Vehicle> vehicles, List<Order> orders) {
+      if (vehicles.Count > 0) {
+        foreach (DynPDPProblemInstance instance in instances) {
+          timeDelta = 0;
+
+          instance.Coordinates = new DoubleMatrix(vehicles.Count + orders.Count * 2, 2);
+          instance.DepotCoordinates = new DoubleMatrix(vehicles.Count, 2);
+          instance.ReadyTime = new DoubleArray(vehicles.Count + orders.Count * 2);
+          instance.DueTime = new DoubleArray(vehicles.Count + orders.Count * 2);
+
+          instance.Capacity = new DoubleArray(vehicles.Count);
+          instance.VehicleDepotAssignment = new IntArray(vehicles.Count);
+          instance.VehicleUsed = new BoolArray(vehicles.Count);
+          instance.VehicleStates.Clear();
+          for (int i = 0; i < vehicles.Count; i++) {
+            instance.VehicleStates.Add(VehicleState.Parked);
+          }
+
+          int depotIdx = 0;
+          int vehicleIdx = 0;
+          foreach (Vehicle vehicle in vehicles) {
+            vehicleAssignment[vehicleIdx] = vehicle.Id;
+
+            instance.Coordinates[depotIdx, 0] = vehicle.DepotX;
+            instance.Coordinates[depotIdx, 1] = vehicle.DepotY;
+            instance.DepotCoordinates[depotIdx, 0] = vehicle.DepotX;
+            instance.DepotCoordinates[depotIdx, 1] = vehicle.DepotY;
+
+            instance.ReadyTime[vehicleIdx] = 0;
+            instance.DueTime[vehicleIdx] = vehicle.DueTime;
+
+            instance.Capacity[vehicleIdx] = vehicle.Capacity;
+            instance.VehicleDepotAssignment[vehicleIdx] = depotIdx;
+
+            depotIdx++;
+            vehicleIdx++;
+          }
+
+          instance.Depots.Value = depotIdx;
+          instance.Vehicles.Value = vehicleIdx;
+
+          foreach (PotvinEncoding solution in solutions) {
+            (solution.VehicleAssignment as IStringConvertibleArray).Length = instance.Vehicles.Value;
+          }
+
+          instance.Demand = new DoubleArray(orders.Count * 2);
+          instance.ServiceTime = new DoubleArray(orders.Count * 2);
+          instance.PickupDeliveryLocation = new IntArray(orders.Count * 2);
+
+          int customerIdx = 0;
+          foreach (Order order in orders) {
+            AddOrder(instance, order, ref customerIdx, ref depotIdx);
+          }
+
+          if (customerIdx != orders.Count * 2) {
+            (instance.Coordinates as IStringConvertibleMatrix).Rows = vehicles.Count + customerIdx;
+            (instance.ReadyTime as IStringConvertibleArray).Length = vehicles.Count + customerIdx;
+            (instance.DueTime as IStringConvertibleArray).Length = vehicles.Count + customerIdx;
+            (instance.Demand as IStringConvertibleArray).Length = customerIdx;
+            (instance.ServiceTime as IStringConvertibleArray).Length = customerIdx;
+            (instance.PickupDeliveryLocation as IStringConvertibleArray).Length = customerIdx;
+          }
+
+          instance.ResetDistanceMatrix();
+          instance.Initialize();
+        }
+        initialized = true;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/BestInsertion.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/BestInsertion.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/BestInsertion.cs	(revision 16099)
@@ -0,0 +1,157 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using System.Threading;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading.Tasks;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("BestInsertion", "A best insertion local update optimization.")]
+  [StorableClass]
+  public class BestInsertion : DynamicPDPOptimization {    
+    public BestInsertion(): base() {
+    }
+    [StorableConstructor]
+    private BestInsertion(bool deserializing) : base(deserializing) {
+    }
+    private BestInsertion(BestInsertion original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BestInsertion(this, cloner);
+    }
+
+    public static void RouteUnrouted(IVRPProblemInstance instance, PotvinEncoding solution) {
+      DynPDPProblemInstance pdp = instance as DynPDPProblemInstance;
+      
+      while (solution.Unrouted.Count > 0) {
+        int city = solution.Unrouted[0];
+        int dest = pdp.GetPickupDeliveryLocation(city);
+
+        int source, target;
+        if (instance.GetDemand(city) >= 0) {
+          source = city;
+          target = dest;
+        } else {
+          source = dest;
+          target = city;
+        }
+
+        //consider creating new tours
+        int tours = solution.Tours.Count;
+        
+        for (int i = tours; i < solution.VehicleAssignment.Length; i++) {
+          Tour newTour = new Tour();
+          solution.Tours.Add(newTour);
+        }
+
+        double minCosts = double.MaxValue;
+        Tour insertTour = null;
+        int sourceLocation = -1;
+        int targetLocation = -1;  
+
+        foreach (Tour tour in solution.Tours) {
+          VRPEvaluation eval = instance.Evaluate(solution);
+
+          for (int i = 0; i <= tour.Stops.Count; i++) {
+            tour.Stops.Insert(i, source);
+            VRPEvaluation tourEval = instance.Evaluate(solution);
+            double sourceCosts = tourEval.Quality - eval.Quality;
+
+            if (tour.Stops.Count == 1) {
+              int vehicle = solution.VehicleAssignment[solution.Tours.IndexOf(tour)];
+              if (!pdp.VehicleUsed[vehicle])
+                sourceCosts += instance.FleetUsageFactor.Value;
+            }
+
+
+            if (source != target) {
+              for (int j = i + 1; j <= tour.Stops.Count; j++) {
+                bool feasible;
+                double targetCosts = instance.GetInsertionCosts(tourEval, solution, target, solution.Tours.IndexOf(tour), j, out feasible);
+
+                double costs = sourceCosts + targetCosts;
+                if (costs < minCosts) {
+                  minCosts = costs;
+                  insertTour = tour;
+                  sourceLocation = i;
+                  targetLocation = j;
+                }
+              }
+            } else {
+              double costs = sourceCosts;
+              if (costs < minCosts) {
+                minCosts = costs;
+                insertTour = tour;
+                sourceLocation = i;
+                targetLocation = -1;
+              }
+            }
+            tour.Stops.Remove(source);
+          }
+        }
+
+        insertTour.Stops.Insert(sourceLocation, source);
+        if (source != target) {
+          insertTour.Stops.Insert(targetLocation, target);
+        }
+
+        solution.Unrouted.Remove(source);
+        if (source != target) {
+          solution.Unrouted.Remove(target);
+        }
+
+        solution.Repair();
+      }
+    }
+
+    protected override void PrepareInstance(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
+      instance.StaticInstance.Vehicles.Value = changeInformation.CreatedVehicles.Count;
+      instance.SetCurrentPlan(new PotvinEncoding(instance.StaticInstance));
+      instance.InitializeInstance(changeInformation.CreatedVehicles, changeInformation.CreatedOrders);
+    }
+
+    protected override bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
+     PotvinEncoding solution = instance.Solutions.First();
+
+     RouteUnrouted(instance.StaticInstance, solution);
+
+     PerformPlan(solution);
+
+     return true;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs	(revision 16099)
@@ -0,0 +1,130 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("Dispatching", "")]
+  [StorableClass]
+  public abstract class Dispatching : DynamicPDPOptimization {
+
+    private bool IsIdle(Vehicle v) {
+      return v.CurrentOrder == Guid.Empty;
+    }
+
+    protected override bool OptimizationRequired(ChangeInformation changeInformation) {
+      // either there are vehicles waiting and there are orders to dispatch
+      // or there are new orders and waiting vehicles
+      return (GetVehicles().Any(x => IsIdle(x))
+        && GetOrders().Any(x => x.AssignedVehicle == Guid.Empty || GetVehicles().Any(y => IsIdle(y) && x.AssignedVehicle == y.Id)));
+    }
+
+
+    [StorableConstructor]
+    protected Dispatching(bool deserializing) : base(deserializing) { }
+    protected Dispatching(Dispatching original, Cloner cloner) : base(original, cloner) { }
+    protected Dispatching() {
+    }
+
+    protected override bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
+      var waitingVehicles = GetVehicles().Where(x => IsIdle(x)).ToList();
+      var waitingOrders = GetOrders().Where(x => x.AssignedVehicle == Guid.Empty).ToList();
+
+      while (waitingVehicles.Any() && (waitingOrders.Any()
+        || GetOrders().Any(x => x.OrderState == OrderState.PickedUp && waitingVehicles.Any(y => y.Id == x.AssignedVehicle)))) {
+        var tmp = new Dictionary<Vehicle, Tuple<Order, double>>();
+        foreach (var vehicle in waitingVehicles) {
+          var pickedupOrders = GetOrders().Where(x => x.OrderState == OrderState.PickedUp && x.AssignedVehicle == vehicle.Id);
+          var orders = waitingOrders.Concat(pickedupOrders);
+          if (orders.Any()) {
+            Order selectedOrder;
+            double priority;
+            GetHighestPriorityOrder((DynPDPProblemInstance)instance.StaticInstance, vehicle, orders, out selectedOrder, out priority);
+            tmp[vehicle] = Tuple.Create(selectedOrder, priority);
+          }
+        }
+        var assignment = tmp.GroupBy(x => x.Value.Item1, x => new { Vehicle = x.Key, Priority = x.Value.Item2 });
+        foreach (var a in assignment) {
+          var bestVehicle = a.MaxItems(x => x.Priority).Select(x => x.Vehicle).First();
+          var order = a.Key;
+
+          bool first = true;
+
+          XY target;
+          MoveVehicleAction action;
+          if (order.OrderState == OrderState.Waiting) {
+            target = new XY(order.PickupXCoord, order.PickupYCoord);
+            action = new MoveVehicleAction(bestVehicle.Id, order.PickupXCoord, order.PickupYCoord, VehicleAction.Pickup, order, scenario.AllowDiversion, scenario.DistanceMeasure);
+          } else {
+            target = new XY(order.DeliveryXCoord, order.DeliveryYCoord);
+            action = new MoveVehicleAction(bestVehicle.Id, order.DeliveryXCoord, order.DeliveryYCoord, VehicleAction.Deliver, order, scenario.AllowDiversion, scenario.DistanceMeasure);
+          }
+          var pickedupOrders = GetOrders().Where(x => x.OrderState == OrderState.PickedUp && x.AssignedVehicle == bestVehicle.Id);
+          var pickedupOrdersAtDestination = pickedupOrders.Where(o => o.DeliveryXCoord == target.X && o.DeliveryYCoord == target.Y);
+          List<MoveVehicleAction> deliveryActions = new List<MoveVehicleAction>();
+          foreach (var pickedupOrder in pickedupOrdersAtDestination) {
+            if (pickedupOrder != order) {
+              MoveVehicleAction deliveryAction = new MoveVehicleAction(bestVehicle.Id, pickedupOrder.DeliveryXCoord, pickedupOrder.DeliveryYCoord, VehicleAction.Deliver, pickedupOrder, scenario.AllowDiversion, scenario.DistanceMeasure);
+              if (first) {
+                SetAction(deliveryAction);
+                first = false;
+              } else {
+                AppendAction(deliveryAction);
+              }
+              waitingOrders.Remove(pickedupOrder);
+            }
+          }
+
+          if (first) {
+            SetAction(action);
+            first = false;
+          } else {
+            AppendAction(action);
+          }
+          waitingVehicles.Remove(bestVehicle);
+          waitingOrders.Remove(order);
+
+          foreach (var assignedOrder in GetOrders().Where(o => o.AssignedVehicle == bestVehicle.Id && o.OrderState == OrderState.Waiting))
+            assignedOrder.AssignedVehicle = Guid.Empty;
+
+          order.AssignedVehicle = bestVehicle.Id;
+        }
+      }
+      return true;
+    }
+
+    protected abstract void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority);
+
+    protected bool IsPickup(Order o, DynPDPProblemInstance instance) {
+      return instance.Demand[Instance.GetStops(o.Id).First()] > 0;
+    }
+
+    protected struct XY {
+      public double X { get; private set; }
+      public double Y { get; private set; }
+
+      public XY(double x, double y)
+        : this() {
+        X = x;
+        Y = y;
+      }
+    }
+
+    protected class XYEqComparer : EqualityComparer<XY> {
+      public override bool Equals(XY x, XY y) {
+        return x.X == y.X && x.Y == y.Y;
+      }
+
+      public override int GetHashCode(XY obj) {
+        return obj.X.GetHashCode() ^ obj.Y.GetHashCode();
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs	(revision 16099)
@@ -0,0 +1,33 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("EarliestDueTimeDispatching", "")]
+  [StorableClass]
+  public class EarliestDueTimeDispatching : Dispatching {
+    [StorableConstructor]
+    protected EarliestDueTimeDispatching(bool deserializing) : base(deserializing) { }
+    protected EarliestDueTimeDispatching(EarliestDueTimeDispatching original, Cloner cloner) : base(original, cloner) { }
+    public EarliestDueTimeDispatching() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new EarliestDueTimeDispatching(this, cloner);
+    }
+
+    protected override void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
+      order = orders.OrderBy(o => IsPickup(o, instance) ? o.PickupDueTime : o.DeliveryDueTime).First();
+      priority = - scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY,
+        IsPickup(order, instance) ? order.PickupXCoord : order.DeliveryXCoord, IsPickup(order, instance) ? order.PickupYCoord : order.DeliveryYCoord);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/LinearPriorityDispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/LinearPriorityDispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/LinearPriorityDispatching.cs	(revision 16099)
@@ -0,0 +1,61 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("LinearPriorityDispatching", "")]
+  [StorableClass]
+  public class LinearPriorityDispatching : PriorityDispatching {
+
+    public IValueLookupParameter<RealVector> WeightsParameter {
+      get { return (IValueLookupParameter<RealVector>)Parameters["Weights"]; }
+    }
+
+    [StorableConstructor]
+    protected LinearPriorityDispatching(bool deserializing) : base(deserializing) { }
+    protected LinearPriorityDispatching(PriorityDispatching original, Cloner cloner) : base(original, cloner) { }
+    public LinearPriorityDispatching() {
+      Parameters.Add(new ValueLookupParameter<RealVector>("Weights", "The weights for the individual priorities."));
+      WeightsParameter.Value = new RealVector(new double[] {
+         100.000, 100.000,  22.349,  74.573,  18.424,  28.913,   0.331,  91.323,  36.969,  44.992,  64.892,  30.736,  23.113,  36.458,   6.178,  99.065, 100.0, 100.0
+      });
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LinearPriorityDispatching(this, cloner);
+    }
+
+    protected override double CalculatePriority(IDictionary<string, double> variables) {
+      var weights = WeightsParameter.Value;
+      
+      double prio = weights[0] * variables["DueDate"]
+             + weights[1] * variables["StartDate"]
+             + weights[2] * variables["PickupOrdersAtTarget"]
+             + weights[3] * variables["Distance"]
+             + weights[4] * variables["AverageDistanceToDestinations"]
+             + weights[5] * variables["MinimumDistanceToDestinations"]
+             + weights[6] * variables["MaximumDistanceToDestinations"]
+             + weights[7] * variables["NumberOfOtherCouriersToTarget"]
+             + weights[8] * variables["AverageDistanceToOtherCouriers"]
+             + weights[9] * variables["EarliestTimeOfArrival"]
+             + weights[10] * variables["DeliveryOrdersAtTarget"]
+             + weights[11] * variables["PickupOrderItemsAtTarget"]
+             + weights[12] * variables["DeliveryOrderItemsAtTarget"]
+             + weights[13] * variables["MinimumDistanceToOtherCouriers"]
+             + weights[14] * variables["MaximumDistanceToOtherCouriers"]
+             + weights[15] * variables["DemandSize"]
+             + weights[16] * variables["EDD"]
+             + weights[17] * variables["LeadTime"];
+
+      return prio;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs	(revision 16099)
@@ -0,0 +1,37 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("NearestDestinationDispatching", "")]
+  [StorableClass]
+  public class NearestDestinationDispatching : Dispatching {
+    [StorableConstructor]
+    protected NearestDestinationDispatching(bool deserializing) : base(deserializing) { }
+    protected NearestDestinationDispatching(NearestDestinationDispatching original, Cloner cloner) : base(original, cloner) { }
+    public NearestDestinationDispatching() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NearestDestinationDispatching(this, cloner);
+    }
+
+    protected override void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
+      order = orders.OrderBy(o => scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY,
+        IsPickup(o, instance) ? o.PickupXCoord : o.DeliveryXCoord, 
+        IsPickup(o, instance) ? o.PickupYCoord : o.DeliveryYCoord)).First();
+
+      priority = - scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY,
+        IsPickup(order, instance) ? order.PickupXCoord : order.DeliveryXCoord, 
+        IsPickup(order, instance) ? order.PickupYCoord : order.DeliveryYCoord);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs	(revision 16099)
@@ -0,0 +1,90 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PriorityDispatching", "")]
+  [StorableClass]
+  public abstract class PriorityDispatching : Dispatching {
+    [StorableConstructor]
+    protected PriorityDispatching(bool deserializing) : base(deserializing) { }
+    protected PriorityDispatching(PriorityDispatching original, Cloner cloner) : base(original, cloner) { }
+    protected PriorityDispatching() {
+    }
+
+    protected abstract double CalculatePriority(IDictionary<string, double> variables);
+
+    protected override void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
+      Order best = null;
+      double bestPriority = double.MinValue;
+      var pickupOrdersByLocation = (from o in orders
+                                   where IsPickup(o, instance)
+                                   group o by new { X = o.PickupXCoord, Y = o.PickupYCoord })
+                                   .ToDictionary(x => new XY(x.Key.X, x.Key.Y), y => y.ToArray(), new XYEqComparer());
+      var deliveryOrdersByLocation = (from o in orders
+                                      where !IsPickup(o, instance) && o.Vehicle == vehicle.Id
+                                      group o by new { X = o.DeliveryXCoord, Y = o.DeliveryYCoord })
+                                      .ToDictionary(x => new XY(x.Key.X, x.Key.Y), y => y.ToArray(), new XYEqComparer());
+      var destinations = deliveryOrdersByLocation.Keys.ToArray();
+      foreach (var o in orders) {
+        if (IsPickup(o, instance) && o.Demand > vehicle.Capacity) continue;
+        
+         double prio;
+         if (!IsPickup(o, instance) && vehicle.TargetPositionX == o.DeliveryXCoord && vehicle.TargetPositionY == o.DeliveryYCoord) {
+           prio = double.MaxValue;
+         } else {
+           var target = new XY(o.PickupXCoord, o.PickupYCoord);
+           if (!IsPickup(o, instance)) target = new XY(o.DeliveryXCoord, o.DeliveryYCoord);
+
+           var destinationDifference = destinations.Select(x => scenario.DistanceMeasure.GetDistance(target.X, target.Y, x.X, x.Y)).ToArray();
+           var courierDifference = GetVehicles().Where(x => x != vehicle).Select(x => new XY(x.TargetPositionX, x.TargetPositionY))
+             .Select(x => scenario.DistanceMeasure.GetDistance(target.X, target.Y, x.X, x.Y)).ToArray();
+
+           var commonDestinations = orders.Where(x => !IsPickup(x, instance) && x.Vehicle == vehicle.Id &&
+                                    x.DeliveryXCoord == o.PickupXCoord &&
+                                    x.DeliveryYCoord == o.PickupYCoord);
+
+           var variables = new Dictionary<string, double>();
+           variables.Add("Distance", scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY, target.X, target.Y));
+           variables.Add("EarliestTimeOfArrival", vehicle.ReadyTime + variables["Distance"]);
+           variables.Add("DueDate", o.DeliveryDueTime - GetSimulationTime());
+           variables.Add("StartDate", IsPickup(o, instance) ? o.PickupReadyTime - GetSimulationTime() : 0);
+           variables.Add("PickupOrdersAtTarget", pickupOrdersByLocation.ContainsKey(target) ? pickupOrdersByLocation[target].Count() : 0);
+           variables.Add("PickupOrderItemsAtTarget", pickupOrdersByLocation.ContainsKey(target) ? pickupOrdersByLocation[target].Sum(x => x.Demand) : 0);
+           variables.Add("DeliveryOrdersAtTarget", deliveryOrdersByLocation.ContainsKey(target) ? deliveryOrdersByLocation[target].Count() : 0);
+           variables.Add("DeliveryOrderItemsAtTarget", deliveryOrdersByLocation.ContainsKey(target) ? deliveryOrdersByLocation[target].Sum(x => x.Demand) : 0);
+           variables.Add("AverageDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Average() : 0);
+           variables.Add("MinimumDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Min() : 0);
+           variables.Add("MaximumDistanceToDestinations", destinationDifference.Any() ? destinationDifference.Max() : 0);
+           variables.Add("NumberOfOtherCouriersToTarget", GetVehicles().Count > 2 ? GetVehicles().Where(x => x != vehicle).Count(x => target.X == x.TargetPositionX && target.Y == x.TargetPositionY) : 0);
+           variables.Add("AverageDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Average() : 0);
+           variables.Add("MinimumDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Min() : 0);
+           variables.Add("MaximumDistanceToOtherCouriers", courierDifference.Any() ? courierDifference.Max() : 0);
+           variables.Add("DemandSize", o.Demand);
+           variables.Add("EDD", commonDestinations.Any() ? commonDestinations.Min(d => d.DeliveryDueTime
+             - scenario.DistanceMeasure.GetDistance(vehicle.TargetPositionX, vehicle.TargetPositionY, d.DeliveryXCoord, d.DeliveryYCoord)
+             - GetSimulationTime()) : 0);
+           variables.Add("LeadTime", o.PickupReadyTime - GetSimulationTime());
+
+           prio = CalculatePriority(variables);
+         }
+
+        if (prio > bestPriority) {
+          bestPriority = prio;
+          best = o;
+        }
+      }
+
+      order = best != null ? best : orders.First();
+      priority = bestPriority;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/TreePriorityDispatching.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/TreePriorityDispatching.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/TreePriorityDispatching.cs	(revision 16099)
@@ -0,0 +1,54 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("TreePriorityDispatching", "")]
+  [StorableClass]
+  public class TreePriorityDispatching : PriorityDispatching {
+    public IValueLookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (IValueLookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+
+    public IValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (IValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters["SymbolicExpressionTreeInterpreter"]; }
+    }
+
+    [StorableConstructor]
+    protected TreePriorityDispatching(bool deserializing) : base(deserializing) { }
+    protected TreePriorityDispatching(PriorityDispatching original, Cloner cloner) : base(original, cloner) { }
+    public TreePriorityDispatching() {
+      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic data analysis solution encoded as a symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>("SymbolicExpressionTreeInterpreter", "The interpreter that should be used to calculate the output values of the symbolic data analysis tree.")); 
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TreePriorityDispatching(this, cloner);
+    }
+
+    protected override double CalculatePriority(IDictionary<string, double> variables) {
+      var tree = SymbolicExpressionTreeParameter.Value;
+      var interpreter = SymbolicDataAnalysisTreeInterpreterParameter.Value;
+
+      Dataset ds = new Dataset(variables.Keys, variables.Values.Select(v => new List<double>(new double[] { v })));
+
+      List<int> rows = new List<int>();
+      rows.Add(0);
+
+      double prio = interpreter.GetSymbolicExpressionTreeValues(tree, ds, rows).First();
+
+      return prio;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/Reoptimization/PFIHReoptimization.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/Reoptimization/PFIHReoptimization.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/Reoptimization/PFIHReoptimization.cs	(revision 16099)
@@ -0,0 +1,172 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using System.Threading;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Variants;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading.Tasks;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PFIHReoptimization", "A pickup and delivery PFIH optimization.")]
+  [StorableClass]
+  public class PFIHReoptimization : DynamicPDPOptimization {
+    public IValueParameter<DoubleValue> Alpha {
+      get { return (IValueParameter<DoubleValue>)Parameters["Alpha"]; }
+    }
+    public IValueParameter<DoubleValue> AlphaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["AlphaVariance"]; }
+    }
+    public IValueParameter<DoubleValue> Beta {
+      get { return (IValueParameter<DoubleValue>)Parameters["Beta"]; }
+    }
+    public IValueParameter<DoubleValue> BetaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["BetaVariance"]; }
+    }
+    public IValueParameter<DoubleValue> Gamma {
+      get { return (IValueParameter<DoubleValue>)Parameters["Gamma"]; }
+    }
+    public IValueParameter<DoubleValue> GammaVariance {
+      get { return (IValueParameter<DoubleValue>)Parameters["GammaVariance"]; }
+    }
+
+    public ValueParameter<IntValue> SampleSizeParameter {
+      get { return (ValueParameter<IntValue>)Parameters["SampleSize"]; }
+    }
+
+    public ValueParameter<BoolValue> ComputeInParallelParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["ComputeInParallel"]; }
+    }
+    
+    public PFIHReoptimization(): base() {
+      Parameters.Add(new ValueParameter<DoubleValue>("Alpha", "The alpha value.", new DoubleValue(0.7)));
+      Parameters.Add(new ValueParameter<DoubleValue>("AlphaVariance", "The alpha variance.", new DoubleValue(0.5)));
+      Parameters.Add(new ValueParameter<DoubleValue>("Beta", "The beta value.", new DoubleValue(0.1)));
+      Parameters.Add(new ValueParameter<DoubleValue>("BetaVariance", "The beta variance.", new DoubleValue(0.07)));
+      Parameters.Add(new ValueParameter<DoubleValue>("Gamma", "The gamma value.", new DoubleValue(0.2)));
+      Parameters.Add(new ValueParameter<DoubleValue>("GammaVariance", "The gamma variance.", new DoubleValue(0.14)));
+
+      Parameters.Add(new ValueParameter<IntValue>("SampleSize", "The sample size.", new IntValue(10)));
+      Parameters.Add(new ValueParameter<BoolValue>("ComputeInParallel", "Indicates if the samples should be computed in parallel.", new BoolValue(true)));
+    }
+    [StorableConstructor]
+    private PFIHReoptimization(bool deserializing) : base(deserializing) {
+    }
+    private PFIHReoptimization(PFIHReoptimization original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PFIHReoptimization(this, cloner);
+    }
+
+    class PFIHResult {
+      public PFIHResult() {
+        bestFeasible = false;
+        bestQuality = double.MaxValue;
+        bestSolution = null;
+      }
+
+      public bool bestFeasible;
+      public double bestQuality;
+      public IVRPEncoding bestSolution;
+    }
+
+    private IVRPEncoding Optimize(DynamicPDProblemInstance instance) {
+      List<bool> vehicleUsed = new List<bool>();
+      for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++) {
+        Vehicle vehicle = GetVehicle(instance.GetVehicle(i));
+        vehicleUsed.Add(vehicle.Distance > 0);
+      }
+
+      int sampleSize = SampleSizeParameter.Value.Value;
+      PFIHResult bestResult = new PFIHResult();
+
+      var options = new ParallelOptions();
+      if (ComputeInParallelParameter.Value.Value)
+        options.MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount - 1, 1);
+      else
+        options.MaxDegreeOfParallelism = 1;
+
+      IRandom random = new HeuristicLab.Random.MersenneTwister(1234);
+
+      Parallel.For<PFIHResult>(0, sampleSize, options,
+        () => new PFIHResult(),
+        (i, loop, result) => {
+          IVRPEncoding current = DynPushForwardInsertionCreator.CreateSolution(instance.StaticInstance,
+                  random, vehicleUsed,
+                  Alpha.Value.Value, Beta.Value.Value, Gamma.Value.Value,
+                  AlphaVariance.Value.Value, BetaVariance.Value.Value, GammaVariance.Value.Value);
+
+          VRPEvaluation eval = instance.StaticInstance.Evaluate(current);
+          double quality = eval.Quality;
+          bool feasible = instance.StaticInstance.Feasible(eval);
+
+          if ((feasible && !result.bestFeasible) || (feasible == result.bestFeasible && quality < result.bestQuality)) {
+            result.bestQuality = quality;
+            result.bestSolution = current;
+            result.bestFeasible = feasible;
+          }
+
+          return result;
+        },
+        (result) => {
+          lock (bestResult) {
+            if ((result.bestFeasible && !bestResult.bestFeasible) || (result.bestFeasible == bestResult.bestFeasible && result.bestQuality < bestResult.bestQuality)) {
+              bestResult.bestQuality = result.bestQuality;
+              bestResult.bestSolution = result.bestSolution;
+              bestResult.bestFeasible = result.bestFeasible;
+            }
+          }
+        }
+        );
+
+      //Recourse
+      if (!bestResult.bestFeasible) {
+        PotvinEncoding currentPlan = (instance.StaticInstance as DynPDPProblemInstance).CurrentPlan;
+        BestInsertion.RouteUnrouted(instance.StaticInstance, currentPlan);
+        bestResult.bestSolution = currentPlan;
+      }
+
+      return bestResult.bestSolution;
+    }
+
+    protected override bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation) {
+
+      IVRPEncoding solution = Optimize(instance);
+      PerformPlan(solution);
+
+      return true;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DefaultDynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DefaultDynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DefaultDynPDPParser.cs	(revision 16099)
@@ -0,0 +1,84 @@
+﻿#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.IO;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.PDPSimulation {
+  class DefaultDynPDPParser: DynPDPParser {
+    public DefaultDynPDPParser(string file): base(file) {
+    }
+
+    public override void Parse() {
+      string line;
+      Regex reg = new Regex(@"-?\d+");
+      MatchCollection m;
+
+      StreamReader reader = new StreamReader(file);
+
+      line = reader.ReadLine();
+      problemName = line;
+
+      line = reader.ReadLine();
+      int vehicleCount = int.Parse(line);
+
+      for (int i = 0; i < vehicleCount; i++) {
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+        Vehicle v = new Vehicle();
+
+        v.xCoord = double.Parse(m[0].Value);
+        v.yCoord = double.Parse(m[1].Value);
+        v.capacity = double.Parse(m[2].Value);
+        v.readyTime = double.Parse(m[3].Value);
+        v.dueTime = double.Parse(m[4].Value);
+
+        vehicles.Add(v);
+      }
+
+      line = reader.ReadLine();
+      int orderCount = int.Parse(line);
+      m = reg.Matches(line);
+      for (int i = 0; i < orderCount; i++) {
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+        Order o = new Order();
+
+        o.revealedTime = double.Parse(m[0].Value);
+        o.pickupXCoord = double.Parse(m[1].Value);
+        o.pickupYCoord = double.Parse(m[2].Value);
+        o.deliveryXCoord = double.Parse(m[3].Value);
+        o.deliveryYCoord = double.Parse(m[4].Value);
+        o.demand = double.Parse(m[5].Value);
+        o.pickupServiceTime = double.Parse(m[6].Value);
+        o.pickupReadyTime = double.Parse(m[7].Value);
+        o.pickupDueTime = double.Parse(m[8].Value);
+        o.deliveryServiceTime = double.Parse(m[9].Value);
+        o.deliveryReadyTime = double.Parse(m[10].Value);
+        o.deliveryDueTime = double.Parse(m[11].Value);
+
+        orders.Add(o);
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/DynPDPParser.cs	(revision 16099)
@@ -0,0 +1,83 @@
+﻿#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.IO;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.PDPSimulation {
+  abstract class DynPDPParser {
+    public struct Vehicle {
+      public double xCoord;
+      public double yCoord;
+      public double capacity;
+      public double readyTime;
+      public double dueTime;
+    }
+
+    public struct Order {
+      public double revealedTime;
+      public double pickupXCoord;
+      public double pickupYCoord;
+      public double deliveryXCoord;
+      public double deliveryYCoord;
+      public double demand;
+      public double pickupServiceTime;
+      public double pickupReadyTime;
+      public double pickupDueTime;
+      public double deliveryServiceTime;
+      public double deliveryReadyTime;
+      public double deliveryDueTime;
+    }
+
+    protected string file;
+    protected string problemName;
+    protected List<Vehicle> vehicles;
+    protected List<Order> orders;
+
+    public string ProblemName {
+      get {
+        return new string(problemName.ToCharArray());
+      }
+    }
+
+    public Vehicle[] Vehicles {
+      get {
+        return vehicles.ToArray();
+      }
+    }
+
+    public Order[] Orders {
+      get {
+        return orders.ToArray();
+      }
+    }
+
+    public DynPDPParser(string file) {
+      this.file = file;
+      vehicles = new List<Vehicle>();
+      orders = new List<Order>();
+    }
+
+    public abstract void Parse();
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/TSPLibDynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/TSPLibDynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/Parsers/TSPLibDynPDPParser.cs	(revision 16099)
@@ -0,0 +1,117 @@
+﻿#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.IO;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.PDPSimulation {
+  class TSPLibDynPDPParser: DynPDPParser {
+    public TSPLibDynPDPParser(string file): base(file) {
+    }
+
+    public override void Parse() {
+      string line;
+      Regex reg = new Regex(@"-?\d+");
+      MatchCollection m;
+
+      StreamReader reader = new StreamReader(file);
+
+      line = reader.ReadLine();
+      problemName = line.Split(':')[1].Remove(0, 1);
+
+      line = reader.ReadLine();
+      string vehicleLine = problemName = line.Split(':')[1].Remove(0, 1);
+      int vehicleCount = int.Parse(vehicleLine);
+
+      line = reader.ReadLine();
+      string capacityLine = problemName = line.Split(':')[1].Remove(0, 1);
+      int capacity = int.Parse(capacityLine);
+
+      line = reader.ReadLine();
+      string dueTimeLine = problemName = line.Split(':')[1].Remove(0, 1);
+      int dueTime = int.Parse(dueTimeLine);
+
+      List<double> xCoord = new List<double>();
+      List<double> yCoord = new List<double>();
+
+      line = reader.ReadLine();
+      line = reader.ReadLine();
+      m = reg.Matches(line);
+      while (m.Count == 3) {
+        xCoord.Add(double.Parse(m[1].Value));
+        yCoord.Add(double.Parse(m[2].Value));
+
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+      }
+
+      for (int i = 0; i < vehicleCount; i++) {
+        Vehicle v = new Vehicle();
+
+        v.xCoord = xCoord[0];
+        v.yCoord = yCoord[0];
+        v.capacity = capacity;
+        v.readyTime = 0;
+        v.dueTime = dueTime;
+
+        vehicles.Add(v);
+      }
+
+      line = reader.ReadLine();
+      m = reg.Matches(line);
+
+      while (m.Count == 11) {
+        Order o = new Order();
+
+        int pickupId = int.Parse(m[1].Value);
+        int deliveryId = int.Parse(m[2].Value);
+        double pickupTWOpen = double.Parse(m[3].Value);
+        double pickupTWClose = double.Parse(m[4].Value);
+        double pickupServiceTime = double.Parse(m[5].Value);
+        double deliveryTWOpen = double.Parse(m[6].Value);
+        double deliveryTWClose = double.Parse(m[7].Value);
+        double deliveryServiceTime = double.Parse(m[8].Value);
+        double demand = double.Parse(m[9].Value);
+        double revealed = double.Parse(m[10].Value);
+
+        o.revealedTime = revealed;
+        o.pickupXCoord = xCoord[pickupId];
+        o.pickupYCoord = yCoord[pickupId];
+        o.deliveryXCoord = xCoord[deliveryId];
+        o.deliveryYCoord = yCoord[deliveryId];
+        o.demand = demand;
+        o.pickupServiceTime = pickupServiceTime;
+        o.pickupReadyTime = pickupTWOpen;
+        o.pickupDueTime = pickupTWClose;
+        o.deliveryServiceTime = deliveryServiceTime;
+        o.deliveryReadyTime = deliveryTWOpen;
+        o.deliveryDueTime = deliveryTWClose;
+
+        orders.Add(o);
+
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/PickupDeliveryPredefinedOrderGenerator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/PickupDeliveryPredefinedOrderGenerator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/OrderGenerators/PickupDeliveryPredefinedOrderGenerator.cs	(revision 16099)
@@ -0,0 +1,163 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryPredefinedOrderGenerator", "A pickup and delivery order generator.")]
+  [StorableClass]
+  public sealed class PickupDeliveryPredefinedOrderGenerator: PickupDeliveryOrderGenerator {
+    public ValueParameter<IntValue> OrderRangeXParameter {
+      get { return (ValueParameter<IntValue>)Parameters["OrderRangeX"]; }
+    }
+
+    public ValueParameter<IntValue> OrderRangeYParameter {
+      get { return (ValueParameter<IntValue>)Parameters["OrderRangeY"]; }
+    }
+    
+    public ValueParameter<DoubleMatrix> OrdersParameter {
+      get { return (ValueParameter<DoubleMatrix>)Parameters["Orders"]; }
+    }
+
+    public OptionalValueParameter<StringArray> OrderNamesParameter {
+      get { return (OptionalValueParameter<StringArray>)Parameters["OrderNames"]; }
+    }
+    
+    public PickupDeliveryPredefinedOrderGenerator() : base() {
+      Parameters.Add(new ValueParameter<DoubleMatrix>("Orders", new DoubleMatrix()));
+      Parameters.Add(new OptionalValueParameter<StringArray>("OrderNames"));
+      Parameters.Add(new ValueParameter<IntValue>("OrderRangeX", new IntValue(0)));
+      Parameters.Add(new ValueParameter<IntValue>("OrderRangeY", new IntValue(0)));
+
+      OrdersParameter.GetsCollected = false;
+    }
+    [StorableConstructor]
+    private PickupDeliveryPredefinedOrderGenerator(bool deserializing) : base(deserializing) { }
+    private PickupDeliveryPredefinedOrderGenerator(PickupDeliveryPredefinedOrderGenerator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PickupDeliveryPredefinedOrderGenerator(this, cloner);
+    }
+
+    public override double RangeX() {
+      double maxX = OrderRangeXParameter.Value.Value;
+
+      if (maxX == 0) {
+        DoubleMatrix orderMatrix = OrdersParameter.Value;
+
+        for (int i = 0; i < orderMatrix.Rows; i++) {
+          double pickupXCoord = orderMatrix[i, 1];
+          if (pickupXCoord > maxX)
+            maxX = pickupXCoord;
+
+          double deliveryXCoord = orderMatrix[i, 3];
+          if (deliveryXCoord > maxX)
+            maxX = deliveryXCoord;
+        }
+      } 
+
+      return maxX;
+    }
+
+    public override double RangeY() {
+      double maxY = OrderRangeYParameter.Value.Value;
+
+      if (maxY == 0) {
+        DoubleMatrix orderMatrix = OrdersParameter.Value;
+
+        for (int i = 0; i < orderMatrix.Rows; i++) {
+          double pickupYCoord = orderMatrix[i, 2];
+          if (pickupYCoord > maxY)
+            maxY = pickupYCoord;
+
+          double deliveryYCoord = orderMatrix[i, 4];
+          if (deliveryYCoord > maxY)
+            maxY = deliveryYCoord;
+        }
+      }
+
+      return maxY;
+    }
+
+    public override bool MoreOrders(double time) {
+      bool moreOrders = false; 
+      
+      DoubleMatrix orderMatrix = OrdersParameter.Value;
+       for (int i = 0; i < orderMatrix.Rows; i++) {
+         double revealedTime = orderMatrix[i, 0];
+
+         if (revealedTime > time) {
+           moreOrders = true;
+           break;
+         }
+       }
+
+       return moreOrders;
+    }
+
+    public override IEnumerable<Order> GetOrders(double timeStart, double timeEnd) {
+      List<Order> orders = new List<Order>();
+
+      DoubleMatrix orderMatrix = OrdersParameter.Value;
+      for (int i = 0; i < orderMatrix.Rows; i++) {
+        double revealedTime = orderMatrix[i, 0];
+        if ((timeStart == timeEnd && revealedTime == timeStart) || (revealedTime > timeStart && revealedTime <= timeEnd)) {
+          Order order = new Order();
+          order.OrderState = OrderState.Waiting;
+
+          order.Index = i;
+          order.PickupXCoord = orderMatrix[i, 1];
+          order.PickupYCoord = orderMatrix[i, 2];
+          order.DeliveryXCoord = orderMatrix[i, 3];
+          order.DeliveryYCoord = orderMatrix[i, 4];
+          order.Demand = orderMatrix[i, 5];
+          order.PickupServiceTime = orderMatrix[i, 6];
+          order.PickupReadyTime = orderMatrix[i, 7];
+          order.PickupDueTime = orderMatrix[i, 8];
+          order.DeliveryServiceTime = orderMatrix[i, 9];
+          order.DeliveryReadyTime = orderMatrix[i, 10];
+          order.DeliveryDueTime = orderMatrix[i, 11];
+
+          order.ServiceRequest = order.DeliveryDueTime < 0;
+
+          if (OrderNamesParameter.Value != null && i < OrderNamesParameter.Value.Length)
+            order.Name = OrderNamesParameter.Value[i];
+          else
+            order.Name = "Order" + i;
+
+          orders.Add(order);
+        }
+      }
+
+      return orders;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DefaultDynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DefaultDynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DefaultDynPDPParser.cs	(revision 16099)
@@ -0,0 +1,84 @@
+﻿#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.IO;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.PDPSimulation {
+  class DefaultDynPDPParser : DynPDPParser {
+    public DefaultDynPDPParser(string file)
+      : base(file) {
+    }
+
+    public override void Parse() {
+      string line;
+      Regex reg = new Regex(@"-?(\d+\.\d+|\d+)");
+      MatchCollection m;
+
+      using (var reader = new StreamReader(file)) {
+
+        line = reader.ReadLine();
+        problemName = line;
+
+        line = reader.ReadLine();
+        int vehicleCount = int.Parse(line);
+
+        for (int i = 0; i < vehicleCount; i++) {
+          line = reader.ReadLine();
+          m = reg.Matches(line);
+          Vehicle v = new Vehicle();
+
+          v.xCoord = double.Parse(m[0].Value, System.Globalization.CultureInfo.InvariantCulture);
+          v.yCoord = double.Parse(m[1].Value, System.Globalization.CultureInfo.InvariantCulture);
+          v.capacity = double.Parse(m[2].Value, System.Globalization.CultureInfo.InvariantCulture);
+          v.readyTime = double.Parse(m[3].Value, System.Globalization.CultureInfo.InvariantCulture);
+          v.dueTime = double.Parse(m[4].Value, System.Globalization.CultureInfo.InvariantCulture);
+
+          vehicles.Add(v);
+        }
+
+        line = reader.ReadLine();
+        int orderCount = int.Parse(line);
+        m = reg.Matches(line);
+        for (int i = 0; i < orderCount; i++) {
+          line = reader.ReadLine();
+          m = reg.Matches(line);
+          Order o = new Order();
+
+          o.revealedTime = double.Parse(m[0].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.pickupXCoord = double.Parse(m[1].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.pickupYCoord = double.Parse(m[2].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.deliveryXCoord = double.Parse(m[3].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.deliveryYCoord = double.Parse(m[4].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.demand = double.Parse(m[5].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.pickupServiceTime = double.Parse(m[6].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.pickupReadyTime = double.Parse(m[7].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.pickupDueTime = double.Parse(m[8].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.deliveryServiceTime = double.Parse(m[9].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.deliveryReadyTime = double.Parse(m[10].Value, System.Globalization.CultureInfo.InvariantCulture);
+          o.deliveryDueTime = double.Parse(m[11].Value, System.Globalization.CultureInfo.InvariantCulture);
+
+          orders.Add(o);
+        }
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/DynPDPParser.cs	(revision 16099)
@@ -0,0 +1,100 @@
+﻿#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.IO;
+using System.Text.RegularExpressions;
+
+namespace HeuristicLab.PDPSimulation {
+  abstract class DynPDPParser {
+    public struct Vehicle {
+      public double xCoord;
+      public double yCoord;
+      public double capacity;
+      public double readyTime;
+      public double dueTime;
+    }
+
+    public struct Order {
+      public double revealedTime;
+      public double pickupXCoord;
+      public double pickupYCoord;
+      public double deliveryXCoord;
+      public double deliveryYCoord;
+      public double demand;
+      public double pickupServiceTime;
+      public double pickupReadyTime;
+      public double pickupDueTime;
+      public double deliveryServiceTime;
+      public double deliveryReadyTime;
+      public double deliveryDueTime;
+    }
+
+    public struct DistanceMatrixInformation {
+      public bool useDistanceMatrix;
+      public int[,] coordinates;
+      public double[,] matrix;
+    }
+
+    protected string file;
+    protected string problemName;
+    protected List<Vehicle> vehicles;
+    protected List<Order> orders;
+    protected DistanceMatrixInformation distanceMatrix;
+
+    public string ProblemName {
+      get {
+        return new string(problemName.ToCharArray());
+      }
+    }
+
+    public Vehicle[] Vehicles {
+      get {
+        return vehicles.ToArray();
+      }
+    }
+
+    public Order[] Orders {
+      get {
+        return orders.ToArray();
+      }
+    }
+
+    public DistanceMatrixInformation DistanceMatrix {
+      get {
+        return distanceMatrix;
+      } 
+    }
+
+    public DynPDPParser(string file) {
+      this.file = file;
+      vehicles = new List<Vehicle>();
+      orders = new List<Order>();
+      distanceMatrix = new DistanceMatrixInformation();
+      distanceMatrix.useDistanceMatrix = false;
+      distanceMatrix.coordinates = null;
+      distanceMatrix.matrix = null;
+    }
+
+    public abstract void Parse();
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/TSPLibDynPDPParser.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/TSPLibDynPDPParser.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Parsers/TSPLibDynPDPParser.cs	(revision 16099)
@@ -0,0 +1,151 @@
+﻿#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.Collections.Generic;
+using System.IO;
+using System.Text.RegularExpressions;
+using System;
+
+namespace HeuristicLab.PDPSimulation {
+  class TSPLibDynPDPParser : DynPDPParser {
+    public TSPLibDynPDPParser(string file)
+      : base(file) {
+    }
+
+    public override void Parse() {
+      string line;
+      Regex reg = new Regex(@"-?(\d+\.\d+|\d+)");
+      MatchCollection m;
+
+      using (var reader = new StreamReader(file)) {
+
+        line = reader.ReadLine();
+        problemName = line.Split(':')[1].Remove(0, 1);
+
+        line = reader.ReadLine();
+        string vehicleLine = problemName = line.Split(':')[1].Remove(0, 1);
+        int vehicleCount = int.Parse(vehicleLine);
+
+        line = reader.ReadLine();
+        string capacityLine = problemName = line.Split(':')[1].Remove(0, 1);
+        int capacity = int.Parse(capacityLine);
+
+        line = reader.ReadLine();
+        string dueTimeLine = problemName = line.Split(':')[1].Remove(0, 1);
+        int dueTime = int.Parse(dueTimeLine);
+
+        List<int> xCoord = new List<int>();
+        List<int> yCoord = new List<int>();
+
+        line = reader.ReadLine();
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+        while (m.Count == 3) {
+          xCoord.Add(int.Parse(m[1].Value, System.Globalization.CultureInfo.InvariantCulture));
+          yCoord.Add(int.Parse(m[2].Value, System.Globalization.CultureInfo.InvariantCulture));
+
+          line = reader.ReadLine();
+          m = reg.Matches(line);
+        }
+
+        for (int i = 0; i < vehicleCount; i++) {
+          Vehicle v = new Vehicle();
+
+          v.xCoord = xCoord[0];
+          v.yCoord = yCoord[0];
+          v.capacity = capacity;
+          v.readyTime = 0;
+          v.dueTime = dueTime;
+
+          vehicles.Add(v);
+        }
+
+        if (line.Contains("EDGE_WEIGHT_TYPE: EXPLICIT")) {
+          line = reader.ReadLine();
+
+          int count = xCoord.Count;
+
+          distanceMatrix.useDistanceMatrix = true;
+          distanceMatrix.coordinates = new int[count, 2];
+          for (int i = 0; i < count; i++) {
+            distanceMatrix.coordinates[i, 0] = xCoord[i];
+            distanceMatrix.coordinates[i, 1] = yCoord[i];
+          }
+
+          distanceMatrix.matrix = new double[count, count];
+
+          line = reader.ReadLine();
+          m = reg.Matches(line);
+
+          int j = 0;
+          while (m.Count == count) {
+            for (int i = 0; i < count; i++) {
+              distanceMatrix.matrix[i, j] = double.Parse(m[i].Value, System.Globalization.CultureInfo.InvariantCulture);              
+            }
+
+            line = reader.ReadLine();
+            m = reg.Matches(line);
+            j++;
+          }
+
+          if (j != count)
+            throw new Exception("Invalid distance matrix definition");
+        }
+
+        line = reader.ReadLine();
+        m = reg.Matches(line);
+
+        while (m.Count == 11) {
+          Order o = new Order();
+
+          int pickupId = int.Parse(m[1].Value, System.Globalization.CultureInfo.InvariantCulture);
+          int deliveryId = int.Parse(m[2].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double pickupTWOpen = double.Parse(m[3].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double pickupTWClose = double.Parse(m[4].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double pickupServiceTime = double.Parse(m[5].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double deliveryTWOpen = double.Parse(m[6].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double deliveryTWClose = double.Parse(m[7].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double deliveryServiceTime = double.Parse(m[8].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double demand = double.Parse(m[9].Value, System.Globalization.CultureInfo.InvariantCulture);
+          double revealed = double.Parse(m[10].Value, System.Globalization.CultureInfo.InvariantCulture);
+
+          o.revealedTime = revealed;
+          o.pickupXCoord = xCoord[pickupId];
+          o.pickupYCoord = yCoord[pickupId];
+          o.deliveryXCoord = xCoord[deliveryId];
+          o.deliveryYCoord = yCoord[deliveryId];
+          o.demand = demand;
+          o.pickupServiceTime = pickupServiceTime;
+          o.pickupReadyTime = pickupTWOpen;
+          o.pickupDueTime = pickupTWClose;
+          o.deliveryServiceTime = deliveryServiceTime;
+          o.deliveryReadyTime = deliveryTWOpen;
+          o.deliveryDueTime = deliveryTWClose;
+
+          orders.Add(o);
+
+          line = reader.ReadLine();
+          m = reg.Matches(line);
+        }
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryAnalyzer.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryAnalyzer.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryAnalyzer.cs	(revision 16099)
@@ -0,0 +1,284 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Optimization;
+using HeuristicLab.Analysis;
+using HeuristicLab.Data;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryAnalyzer", "A pickup and delivery analyzer.")]
+  [StorableClass]
+  public class PickupDeliveryAnalyzer: ParameterizedNamedItem {
+    public PickupDeliveryAnalyzer() : base() {
+    }
+    [StorableConstructor]
+    protected PickupDeliveryAnalyzer(bool deserializing) : base(deserializing) { }
+    protected PickupDeliveryAnalyzer(PickupDeliveryAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PickupDeliveryAnalyzer(this, cloner);
+    }
+
+    public virtual void UpdateVisualization(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("Visualization"))
+        results.Add(new Result("Visualization", new PickupDeliveryVisualization(simulation)));
+      else
+        (results["Visualization"].Value as PickupDeliveryVisualization).SetState(simulation);
+
+      (results["Visualization"].Value as PickupDeliveryVisualization).Refresh();
+    }
+
+    protected virtual void UpdateOrderResults(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("OrderStatistics")) {
+        DataTable data = new DataTable("OrderStatistics");
+        results.Add(new Result("OrderStatistics", data));
+
+        data.Rows.Add(new DataRow("WaitingOrders"));
+        data.Rows.Add(new DataRow("PickedUpOrders"));
+        data.Rows.Add(new DataRow("DeliveredOrders"));
+        data.Rows.Add(new DataRow("CancelledOrders"));
+
+        results.Add(new Result("AverageQueueLength", new DoubleValue(0)));
+      }
+
+      DataTable orderStatistics = results["OrderStatistics"].Value as DataTable;
+
+      int currentWaiting = 0;
+      int currentPickedUp = 0;
+      int currentDelivered = 0;
+      int currentCancelled = 0;
+
+      foreach (Order order in simulation.Orders) {
+        if (order.OrderState == OrderState.Waiting || order.OrderState == OrderState.PickingUp)
+          currentWaiting++;
+        else if (order.OrderState == OrderState.PickedUp || order.OrderState == OrderState.Delivering)
+          currentPickedUp++;
+        else if (order.OrderState == OrderState.Delivered)
+          currentDelivered++;
+        else if (order.OrderState == OrderState.Cancelled)
+          currentCancelled++;
+      }
+
+      orderStatistics.Rows["WaitingOrders"].Values.Add(currentWaiting);
+      orderStatistics.Rows["PickedUpOrders"].Values.Add(currentPickedUp);
+      orderStatistics.Rows["DeliveredOrders"].Values.Add(currentDelivered);
+      orderStatistics.Rows["CancelledOrders"].Values.Add(currentCancelled);
+
+      DoubleValue queueLength = results["AverageQueueLength"].Value as DoubleValue;
+      queueLength.Value = orderStatistics.Rows["WaitingOrders"].Values.Average();
+    }
+
+    protected virtual void UpdateVehicleResults(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("VehicleStatistics")) {
+        DataTable data = new DataTable("VehicleStatistics");
+        results.Add(new Result("VehicleStatistics", data));
+
+        data.Rows.Add(new DataRow("UsedVehicles"));
+        data.Rows.Add(new DataRow("DrivenDistance"));
+        data.Rows.Add(new DataRow("InvalidActions"));
+        data.Rows.Add(new DataRow("Tardiness"));
+        data.Rows.Add(new DataRow("CapacityUtilization"));
+
+        results.Add(new Result("UsedVehicles", new IntValue()));
+        results.Add(new Result("DrivenDistance", new DoubleValue()));
+        results.Add(new Result("InvalidActions", new DoubleValue()));
+        results.Add(new Result("VehicleTardiness", new DoubleValue()));
+      }
+
+      DataTable vehicleStatistics = results["VehicleStatistics"].Value as DataTable;
+
+      int usedVehicles = simulation.Vehicles.Where(v => v.Distance > 0).Count();
+      double distance = Math.Round(simulation.Vehicles.Sum(v => v.Distance) * 100.0) / 100.0;
+      int invalidActions = simulation.Vehicles.Sum(v => v.InvalidActions);
+      double tardiness = Math.Round(simulation.Vehicles.Sum(v => v.Tardiness) * 100.0) / 100.0;      
+      var used = simulation.Vehicles.Where(v => v.Distance > 0);
+      double capacityUtilization = 0;
+      if(used.Count() > 0)
+        capacityUtilization = Math.Round(used.Average(v => 1.0 - (v.Capacity / v.TotalCapacity)) * 100.0) / 100.0;
+
+      vehicleStatistics.Rows["UsedVehicles"].Values.Add(usedVehicles);
+      vehicleStatistics.Rows["DrivenDistance"].Values.Add(distance);
+      vehicleStatistics.Rows["InvalidActions"].Values.Add(invalidActions);
+      vehicleStatistics.Rows["Tardiness"].Values.Add(tardiness);
+      vehicleStatistics.Rows["CapacityUtilization"].Values.Add(capacityUtilization);
+
+      (results["UsedVehicles"].Value as IntValue).Value = usedVehicles;
+      (results["DrivenDistance"].Value as DoubleValue).Value = distance;
+      (results["VehicleTardiness"].Value as DoubleValue).Value = tardiness;
+    }
+
+    protected virtual void UpdateConstraintViolationResults(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("ConstraintViolations")) {
+        DataTable data = new DataTable("ConstraintViolations");
+        results.Add(new Result("ConstraintViolations", data));
+
+        data.Rows.Add(new DataRow("Overload"));
+        data.Rows.Add(new DataRow("Tardiness"));
+
+        results.Add(new Result("Overload", new DoubleValue()));
+        results.Add(new Result("Tardiness", new DoubleValue()));
+      }
+
+      DataTable violationStatistics = results["ConstraintViolations"].Value as DataTable;
+
+      double overload = Math.Round(simulation.Vehicles.Sum(v => v.Overload) * 100.0) / 100.0;
+      double tardiness = Math.Round(simulation.Orders.Sum(o => o.Tardiness) * 100.0) / 100.0;
+
+      violationStatistics.Rows["Overload"].Values.Add(overload);
+      violationStatistics.Rows["Tardiness"].Values.Add(tardiness);
+
+      (results["Overload"].Value as DoubleValue).Value = overload;
+      (results["Tardiness"].Value as DoubleValue).Value = tardiness;
+    }
+
+    protected virtual void UpdateVehicleHistoryResults(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("VehicleHistory")) {
+        VehicleHistoryVisualization data = new VehicleHistoryVisualization();
+        data.ResultCollectionInterval = simulation.TimeStepParameter.Value.Value;
+        results.Add(new Result("VehicleHistory", data));
+
+        foreach (Vehicle vehicle in simulation.Vehicles) {
+          string name = vehicle.Name;
+          if (string.IsNullOrEmpty(name))
+            name = "Vehicle " + simulation.Vehicles.IndexOf(vehicle);
+
+          data.VehicleHistory.Add(new VehicleHistory(name));
+        }
+      }
+
+      VehicleHistoryVisualization vehicleHistory = results["VehicleHistory"].Value as VehicleHistoryVisualization;
+      foreach (Vehicle vehicle in simulation.Vehicles) {
+        VehicleHistory history = vehicleHistory.VehicleHistory[simulation.Vehicles.IndexOf(vehicle)];
+        history.VehicleState.Add(vehicle.VehicleState);
+        history.VehicleAvailability.Add(vehicle.Availibility);
+        history.ActiveOrders.Add(simulation.Orders.FirstOrDefault(o => o.Id == vehicle.CurrentOrder));
+        history.AssignedOrders.Clear();
+        history.AssignedOrders.AddRange(simulation.Orders.Where(o => o.AssignedVehicle == vehicle.Id));
+      }
+      vehicleHistory.Refresh();
+    }
+
+    protected virtual void UpdateTimeHistogram(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("TimeHistogram")) {
+        DataTable data = new DataTable("TimeHistogram");
+        results.Add(new Result("TimeHistogram", data));
+
+        DataRow row = new DataRow("WaitingTime");
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        data.Rows.Add(row);
+
+        row = new DataRow("TransferTime");
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        data.Rows.Add(row);
+
+        row = new DataRow("Slack");
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        data.Rows.Add(row);
+
+        row = new DataRow("LeadTime");
+        row.VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Histogram;
+        data.Rows.Add(row);
+
+        results.Add(new Result("LeadTime", new DoubleValue()));
+
+        results.Add(new Result("TotalTardinessPenalty", new DoubleValue()));
+      }
+
+      DataTable timeHistogram = results["TimeHistogram"].Value.Clone() as DataTable;
+
+      //waiting time
+      var values = timeHistogram.Rows["WaitingTime"].Values;
+      values.Clear();
+      foreach (Order order in simulation.Orders.Where(o => o.PickupTime > 0)) {
+        values.Add(order.PickupTime - order.PickupReadyTime);
+      }
+
+      //transfer time
+      values = timeHistogram.Rows["TransferTime"].Values;
+      values.Clear();
+      foreach (Order order in simulation.Orders.Where(o => o.OrderState == OrderState.Delivered)) {
+        values.Add(order.DeliveryTime - order.PickupTime - order.PickupServiceTime);
+      }
+
+      //slack
+      values = timeHistogram.Rows["Slack"].Values;
+      values.Clear();
+      foreach (Order order in simulation.Orders.Where(o => o.PickupTime > 0)) {
+        values.Add(order.PickupDueTime - order.PickupTime);
+      }
+
+      //lead time
+      double leadTime = 0;
+
+      values = timeHistogram.Rows["LeadTime"].Values;
+      values.Clear();
+      foreach (Order order in simulation.Orders.Where(o => o.OrderState == OrderState.Delivered)) {
+        double orderLeadTime = order.DeliveryTime + order.DeliveryServiceTime - order.PickupReadyTime;
+        values.Add(orderLeadTime);
+        leadTime += orderLeadTime;
+      }
+
+      (results["LeadTime"].Value as DoubleValue).Value = leadTime;
+
+      results["TimeHistogram"].Value = timeHistogram;
+
+      double tardiness = 0;
+      foreach(Order o in simulation.Orders) {
+        if(o.Tardiness > 0) {
+          tardiness += Math.Min(1000000, Math.Pow((scenario.TardinessPenaltyParameter.Value.Value * Math.E), o.Tardiness) - 1.0);
+        }
+      }
+      (results["TotalTardinessPenalty"].Value as DoubleValue).Value = tardiness;
+    }
+
+    protected virtual void UpdateSimulationTime(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      if (!results.ContainsKey("SimulationTime")) {
+        results.Add(new Result("SimulationTime", new DoubleValue()));
+      }
+
+      (results["SimulationTime"].Value as DoubleValue).Value = simulation.SimulationTime;
+    }
+
+    public virtual void Analyze(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+      UpdateSimulationTime(simulation, scenario, results);
+      UpdateOrderResults(simulation, scenario, results);
+      UpdateVehicleResults(simulation, scenario, results);
+      UpdateConstraintViolationResults(simulation, scenario, results);
+      UpdateVehicleHistoryResults(simulation, scenario, results);
+      UpdateTimeHistogram(simulation, scenario, results);
+    }
+
+    public virtual void Tick(PickupDeliverySimulation simulation, PickupDeliveryScenario scenario, ResultCollection results) {
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOptimization.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOptimization.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOptimization.cs	(revision 16099)
@@ -0,0 +1,376 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PDPSimulation.SimulationCore;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryOptimization", "A pickup and delivery optimization.")]
+  [StorableClass]
+  public abstract class PickupDeliveryOptimization: ParameterizedNamedItem {
+    #region constructors
+    public PickupDeliveryOptimization() : base() {
+      objectChanges = new Dictionary<BaseObject, List<PDChange>>();
+      actions = new Dictionary<Guid, PDAction>();
+    }
+    [StorableConstructor]
+    protected PickupDeliveryOptimization(bool deserializing) : base(deserializing) { }
+    protected PickupDeliveryOptimization(PickupDeliveryOptimization original, Cloner cloner)
+      : base(original, cloner) {
+      lock (original.objectChanges) {
+        lock (original.actionLocker) {
+          simulation = cloner.Clone<PickupDeliverySimulation>(original.simulation);
+          if (simulation != null) {
+            simulation.SimulationStateChanged +=
+              new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
+          }
+
+          objectChanges = new Dictionary<BaseObject, List<PDChange>>();
+          foreach (BaseObject obj in original.objectChanges.Keys) {
+            BaseObject objClone = cloner.Clone<BaseObject>(obj);
+
+            objectChanges.Add(objClone, new List<PDChange>());
+            foreach (PDChange change in original.objectChanges[obj])
+              objectChanges[objClone].Add(cloner.Clone<PDChange>(change));
+          }
+
+          actions = new Dictionary<Guid, PDAction>();
+          foreach (Guid objId in original.actions.Keys) {
+            actions.Add(objId, cloner.Clone<PDAction>(original.actions[objId]));
+          }
+        }
+      }
+
+      this.scenario = cloner.Clone<PickupDeliveryScenario>(original.scenario);
+      this.waitingStrategy = cloner.Clone<WaitingStrategy>(original.waitingStrategy);
+    }
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (this.simulation != null) {
+        this.simulation.SimulationStateChanged +=
+         new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
+      }
+    }
+
+    [Storable]
+    protected PickupDeliveryScenario scenario;
+
+    [Storable]
+    protected WaitingStrategy waitingStrategy;
+
+    [Storable]
+    private PickupDeliverySimulation simulation;
+
+    protected double GetSimulationTime() {
+      return simulation.SimulationTime;
+    }
+
+    protected double GetTimeStep() {
+      return simulation.TimeStep;
+    }
+
+    protected List<Order> GetOrders() {
+      return simulation.Orders;
+    }
+
+    protected Order GetOrder(Guid orderId) {
+      return simulation.GetOrder(orderId);
+    }
+
+    protected Vehicle GetVehicle(Guid vehicleId) {
+      return simulation.GetVehicle(vehicleId);
+    }
+
+    protected List<Vehicle> GetVehicles() {
+      return simulation.Vehicles;
+    }
+
+    protected ResultCollection GetResults() {
+      return simulation.Results;
+    }
+
+    [Storable]
+    private Dictionary<BaseObject, List<PDChange>> objectChanges;
+
+    private void RemoveObsoleteChanges(PDChange change) {
+      List<PDChange> toBeRemoved = new List<PDChange>();
+
+      foreach (PDChange existingChange in objectChanges[change.BaseObject]) {
+        if (existingChange.ChangeType == change.ChangeType) {
+          toBeRemoved.Add(existingChange);
+        }
+      }
+
+      foreach (PDChange removed in toBeRemoved) {
+        objectChanges[change.BaseObject].Remove(removed);
+      }
+    }
+
+    protected void AddChange(PDChange change) {
+      lock (objectChanges) {
+        if (!objectChanges.ContainsKey(change.BaseObject))
+          objectChanges.Add(change.BaseObject, new List<PDChange>());
+
+        RemoveObsoleteChanges(change);
+
+        objectChanges[change.BaseObject].Add(change);
+      }
+    }
+
+    protected List<PDChange> GetChanges(bool clear) {
+      lock (objectChanges) {
+        List<PDChange> result = new List<PDChange>();
+        foreach (List<PDChange> objChanges in objectChanges.Values)
+          result.AddRange(objChanges);
+
+        if(clear)
+          objectChanges.Clear();
+
+        return result;
+      }
+    }
+
+    protected struct ChangeInformation {
+      public List<Vehicle> CreatedVehicles { get; set; }
+      public List<Order> CreatedOrders { get; set; }
+      public List<Vehicle> ChangedVehicles { get; set; }
+      public List<Order> ChangedOrders { get; set; }
+      public bool InvalidActions { get; set; }
+      public bool SimulationFinished { get; set; }
+    }
+
+    protected ChangeInformation GetChangeInformation(List<PDChange> changes) {
+      ChangeInformation changeInformation = new ChangeInformation();
+
+      changeInformation.CreatedVehicles = new List<Vehicle>();
+      changeInformation.CreatedOrders = new List<Order>();
+      changeInformation.ChangedVehicles = new List<Vehicle>();
+      changeInformation.ChangedOrders = new List<Order>();
+      changeInformation.InvalidActions = false;
+      changeInformation.SimulationFinished = false;
+
+      foreach (PDChange change in changes) {
+        if (change.ChangeType == SimulationStateChange.VehicleCreated) {
+          Vehicle vehicle = change.BaseObject as Vehicle;
+          changeInformation.CreatedVehicles.Add(vehicle);
+        } else if (change.ChangeType == SimulationStateChange.VehicleMoved ||
+           change.ChangeType == SimulationStateChange.VehicleState) {
+          Vehicle vehicle = change.BaseObject as Vehicle;
+          changeInformation.ChangedVehicles.Add(vehicle);
+
+          if (change.ChangeType == SimulationStateChange.VehicleState &&
+            vehicle.VehicleState == VehicleState.InvalidAction)
+            changeInformation.InvalidActions = true;
+        } else if (change.ChangeType == SimulationStateChange.OrderCreated) {
+          Order order = change.BaseObject as Order;
+          changeInformation.CreatedOrders.Add(order);
+        } else if (change.ChangeType == SimulationStateChange.OrderState) {
+          Order order = change.BaseObject as Order;
+          changeInformation.ChangedOrders.Add(order);
+        } else if (change.ChangeType == SimulationStateChange.NoMoreOrders) {
+          changeInformation.SimulationFinished = true;
+        } else if (change.ChangeType == SimulationStateChange.OrderFailed) {
+          changeInformation.InvalidActions = true;
+        }
+      }
+
+      changeInformation.InvalidActions = changeInformation.InvalidActions ||
+        GetVehicles().Where(v => v.VehicleState == VehicleState.InvalidAction).Count() > 0;
+
+      return changeInformation;
+    }
+
+    protected object actionLocker = new object();
+
+    [Storable]
+    private Dictionary<Guid, PDAction> actions;
+
+    public PDAction GetAction(BaseObject obj) {
+      lock (actionLocker) {
+        if (actions.ContainsKey(obj.Id))
+          return actions[obj.Id];
+        else
+          return null;
+      }
+    }
+
+    protected void SetAction(PDAction action) {
+      lock (actionLocker) {
+        if (actions.ContainsKey(action.BaseObjectId)) {
+          lock (actions[action.BaseObjectId]) {
+            if (!actions[action.BaseObjectId].Interruptable())
+              actions[action.BaseObjectId].AppendAction(action, false);
+            else
+              actions[action.BaseObjectId] = action;
+          }
+        } else {
+          actions[action.BaseObjectId] = action;
+        }
+      }
+    }
+
+    protected void AppendAction(PDAction action) {
+      lock (actionLocker) {
+        if (actions.ContainsKey(action.BaseObjectId)) {
+          actions[action.BaseObjectId].AppendAction(action, true);
+        } else {
+          actions[action.BaseObjectId] = action;
+        } 
+      }
+    }
+
+    public void RemoveCompletedActions() {
+      lock (actionLocker) {
+        List<Guid> toBeRemoved = new List<Guid>();
+        foreach (Guid objId in actions.Keys) {
+          if (actions[objId].IsCompleted)
+            toBeRemoved.Add(objId);
+        }
+        foreach (Guid objId in toBeRemoved)
+          actions.Remove(objId);
+      }
+    }
+
+    public List<PDAction> GetActions() {
+      lock (actionLocker) {
+        RemoveCompletedActions();
+
+        return actions.Values.ToList();
+      }
+    }
+
+    public virtual void SetScenario(PickupDeliveryScenario scenario) {
+      if (scenario != null) {
+        this.scenario = scenario;
+      }
+    }
+
+    public virtual void SetWaitingStrategy(WaitingStrategy waitingStrategy) {
+      this.waitingStrategy = waitingStrategy;      
+    }
+
+    public virtual void Prepare() {
+      //clear state
+      objectChanges.Clear();
+      actions.Clear();
+    }
+
+    public virtual void SetSimulation(PickupDeliverySimulation simulation) {
+      if (this.simulation != simulation) {
+        if (this.simulation != null) {
+          this.simulation.SimulationStateChanged -=
+            new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
+        }
+
+        this.simulation = simulation;
+
+        this.simulation.SimulationStateChanged +=
+           new PickupDeliverySimulation.SimulationStateChangedHandler(simulation_SimulationStateChanged);
+      }
+    }
+
+    private EventWaitHandle wh;
+    private void InitWaitHandle(bool synchronized) {
+      if(wh != null)
+        wh.Dispose();
+      wh = null;
+
+      if(synchronized)
+        wh = new EventWaitHandle(false, EventResetMode.AutoReset);
+    }
+    protected void SignalWaitHandle() {
+      if(wh != null)
+        wh.Set();
+    }
+    public void WaitForOptimization() {
+      if (wh != null) {
+        bool signal = false;
+
+        while (!signal && Running())
+          signal = wh.WaitOne(100);
+      }
+    }
+    protected void WaitForSimulation() {
+      simulation.WaitForSimulation();
+    }
+
+    protected abstract void Optimize(CancellationToken token);
+    Thread optThread;
+    CancellationTokenSource cts;
+
+    protected bool running;
+
+    public void Start(bool synchronized) {
+      running = true;
+      InitWaitHandle(synchronized);
+
+      using (EventWaitHandle wh = new EventWaitHandle(false, EventResetMode.ManualReset)) {
+        cts = new CancellationTokenSource();
+        optThread = new Thread(delegate() {
+          wh.Set();
+          Optimize(cts.Token);
+        });
+        optThread.IsBackground = true;
+        optThread.Start();
+
+        wh.WaitOne();
+      }
+    }
+
+    public abstract bool OptimizationRequired();
+
+    public virtual void RelocateVehicles() {
+
+    }
+
+    public void Stop() {
+      if(cts != null)
+       cts.Cancel();
+    }
+
+    public bool Running() {
+      return optThread != null && optThread.IsAlive && running;
+    }
+
+    public void Exit() {
+      optThread = null;
+    }
+
+    void simulation_SimulationStateChanged(BaseObject obj, SimulationStateChange changeType) {
+      PDChange change = new PDChange() { BaseObject = obj.Clone() as BaseObject, ChangeType = changeType };
+      AddChange(change);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOrderGenerator.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOrderGenerator.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryOrderGenerator.cs	(revision 16099)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PDPSimulation.SimulationCore;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryOrderGenerator", "A pickup and delivery order generator.")]
+  [StorableClass]
+  public abstract class PickupDeliveryOrderGenerator: ParameterizedNamedItem {
+    public PickupDeliveryOrderGenerator() : base() {
+    }
+    [StorableConstructor]
+    protected PickupDeliveryOrderGenerator(bool deserializing) : base(deserializing) { }
+    protected PickupDeliveryOrderGenerator(PickupDeliveryOrderGenerator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public abstract IEnumerable<Order> GetOrders(double timeStart, double timeEnd);
+    public abstract bool MoreOrders(double time);
+    public abstract double RangeX();
+    public abstract double RangeY();
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryScenario.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryScenario.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryScenario.cs	(revision 16099)
@@ -0,0 +1,270 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.PDPSimulation.SimulationCore;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.Problems.VehicleRouting.ProblemInstances;
+using HeuristicLab.PDPSimulation.Operators;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryScenario", "A pickup and delivery scenario.")]
+  [StorableClass]
+  public sealed class PickupDeliveryScenario: Scenario {
+    public event EventHandler ScenarioChanged;
+
+    public ValueParameter<DistanceMeasure> DistanceMeasureParameter {
+      get { return (ValueParameter<DistanceMeasure>)Parameters["DistanceMeasure"]; }
+    }
+
+    public ValueParameter<BoolValue> AllowDiversionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["AllowDiversion"]; }
+    }
+    
+    public ValueParameter<DoubleMatrix> DepotCoordinatesParameter {
+      get { return (ValueParameter<DoubleMatrix>)Parameters["DepotCoordinates"]; }
+    }
+
+    public ValueParameter<DoubleArray> VehicleCapacitiesParameter {
+      get { return (ValueParameter<DoubleArray>)Parameters["VehicleCapacities"]; }
+    }
+
+    public ValueParameter<DoubleArray> VehicleReadyTimesParameter {
+      get { return (ValueParameter<DoubleArray>)Parameters["VehicleReadyTimes"]; }
+    }
+
+    public ValueParameter<DoubleArray> VehicleDueTimesParameter {
+      get { return (ValueParameter<DoubleArray>)Parameters["VehicleDueTimes"]; }
+    }
+    
+    public OptionalValueParameter<PickupDeliveryOrderGenerator> OrderGeneratorParameter {
+      get { return (OptionalValueParameter<PickupDeliveryOrderGenerator>)Parameters["PickupDeliveryOrderGenerator"]; }
+    }
+
+    public ValueParameter<MDCVRPTWEvaluator> EvaluatorParameter {
+      get { return (ValueParameter<MDCVRPTWEvaluator>)Parameters["Evaluator"]; }
+    }
+
+    public IValueParameter<DoubleValue> DistanceFactorParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["DistanceFactor"]; }
+    }
+
+    public IValueParameter<DoubleValue> FleetUsageFactorParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["FleetUsageFactor"]; }
+    }
+
+    public IValueParameter<DoubleValue> OverloadPenaltyParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["OverloadPenalty"]; }
+    }
+
+    public IValueParameter<DoubleValue> TardinessPenaltyParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["TardinessPenalty"]; }
+    }
+
+    public IValueParameter<DoubleValue> PickupViolationPenaltyParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters["PickupViolationPenalty"]; }
+    }
+
+    public IValueParameter<BoolValue> RelocateBackToDepotParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["RelocateBackToDepot"]; }
+    }
+
+    public DistanceMeasure DistanceMeasure {
+      get {
+        return DistanceMeasureParameter.Value;
+      }
+      set {
+        DistanceMeasureParameter.Value = value;
+      }
+    }
+
+    public PickupDeliveryOrderGenerator OrderGenerator {
+      get {
+        return OrderGeneratorParameter.Value;
+      }
+      set {
+        OrderGeneratorParameter.Value = value;
+      }
+    }
+
+    public MDCVRPTWEvaluator Evaluator {
+      get {
+        return EvaluatorParameter.Value;
+      }
+
+      set {
+        EvaluatorParameter.Value = value;
+      }
+    }
+
+    public bool AllowDiversion {
+      get {
+        return AllowDiversionParameter.Value.Value &&
+          DistanceMeasure.DiversionSupported;
+      }
+    }
+
+    public bool RelocateBackToDepot {
+      get {
+        return RelocateBackToDepotParameter.Value.Value;
+      }
+    }
+
+    public PickupDeliveryScenario() : base() {
+      Parameters.Add(new ValueParameter<DistanceMeasure>("DistanceMeasure", new EuclideanDistanceMeasure()));
+      Parameters.Add(new ValueParameter<BoolValue>("AllowDiversion", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<DoubleMatrix>("DepotCoordinates", new DoubleMatrix()));
+      Parameters.Add(new ValueParameter<BoolValue>("RelocateBackToDepot", new BoolValue(true)));
+      Parameters.Add(new ValueParameter<DoubleArray>("VehicleCapacities", new DoubleArray()));
+      Parameters.Add(new ValueParameter<DoubleArray>("VehicleReadyTimes", new DoubleArray()));
+      Parameters.Add(new ValueParameter<DoubleArray>("VehicleDueTimes", new DoubleArray()));
+      Parameters.Add(new ValueParameter<DoubleValue>("DistanceFactor", "The distance factor considered in the evaluation.", new DoubleValue(1)));
+      Parameters.Add(new ValueParameter<DoubleValue>("FleetUsageFactor", "The fleet usage factor considered in the evaluation.", new DoubleValue(3000)));
+      Parameters.Add(new ValueParameter<DoubleValue>("OverloadPenalty", "The overload penalty considered in the evaluation.", new DoubleValue(10000)));
+      Parameters.Add(new ValueParameter<DoubleValue>("TardinessPenalty", "The tardiness penalty considered in the evaluation.", new DoubleValue(10000)));
+      Parameters.Add(new ValueParameter<DoubleValue>("PickupViolationPenalty", "The pickup violation penalty considered in the evaluation.", new DoubleValue(1000000)));
+      Parameters.Add(new OptionalValueParameter<PickupDeliveryOrderGenerator>("PickupDeliveryOrderGenerator"));
+      Parameters.Add(new ValueParameter<MDCVRPTWEvaluator>("Evaluator", new DynPDPEvaluator()));
+
+      DepotCoordinatesParameter.GetsCollected = false;
+      VehicleCapacitiesParameter.GetsCollected = false;
+      VehicleReadyTimesParameter.GetsCollected = false;
+      VehicleDueTimesParameter.GetsCollected = false;
+      OrderGeneratorParameter.GetsCollected = false;
+      DistanceMeasureParameter.GetsCollected = false;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey("Evaluator")) {
+        Parameters.Add(new ValueParameter<MDCVRPTWEvaluator>("Evaluator", new DynPDPEvaluator()));
+      }
+    }
+
+    public IEnumerable<Order> GetOrders(double timeStart, double timeEnd) {
+      return OrderGeneratorParameter.Value.GetOrders(timeStart, timeEnd);
+    }
+
+    public bool MoreOrders(double time) {
+      return OrderGeneratorParameter.Value.MoreOrders(time);
+    }
+
+    public double OrderRangeX() {
+      return OrderGeneratorParameter.Value.RangeX();
+    }
+
+    public double OrderRangeY() {
+      return OrderGeneratorParameter.Value.RangeY();
+    }
+
+    private void OnScenarioChanged() {
+      if (ScenarioChanged != null)
+        ScenarioChanged(this, null);
+    }
+
+    private void ImportFromDynPDP(DynPDPParser parser) {
+      parser.Parse();
+
+      int vehicles = parser.Vehicles.Length;
+      DoubleMatrix depotCoordinates = new DoubleMatrix(vehicles, 2);
+      DoubleArray vehicleCapacities = new DoubleArray(vehicles);
+      DoubleArray vehicleReadyTimes = new DoubleArray(vehicles);
+      DoubleArray vehicleDueTimes = new DoubleArray(vehicles);
+
+      for (int i = 0; i < vehicles; i++) {
+        DynPDPParser.Vehicle vehicle = parser.Vehicles[i];
+        depotCoordinates[i, 0] = vehicle.xCoord;
+        depotCoordinates[i, 1] = vehicle.yCoord;
+        vehicleCapacities[i] = vehicle.capacity;
+        vehicleReadyTimes[i] = vehicle.readyTime;
+        vehicleDueTimes[i] = vehicle.dueTime;
+      }
+      DepotCoordinatesParameter.Value = depotCoordinates;
+      VehicleCapacitiesParameter.Value = vehicleCapacities;
+      VehicleReadyTimesParameter.Value = vehicleReadyTimes;
+      VehicleDueTimesParameter.Value = vehicleDueTimes;
+
+      if (parser.DistanceMatrix.useDistanceMatrix) {
+        DistanceMatrixMeasure dm = new DistanceMatrixMeasure();
+
+        dm.PointMapping = new IntMatrix(parser.DistanceMatrix.coordinates);
+        dm.DistanceMatrix = new DoubleMatrix(parser.DistanceMatrix.matrix);
+
+        DistanceMeasure = dm;
+      }
+
+      PickupDeliveryPredefinedOrderGenerator orderGen = new PickupDeliveryPredefinedOrderGenerator();
+      int orders = parser.Orders.Length;
+
+      DoubleMatrix orderMatrix = new DoubleMatrix(orders, 12,
+        new string[] { "Time revealed", "P X coordinate", "P Y coordinate", "D X coordinate", "D Y coordinate",
+        "Demand", "P service time", "P ready time", "P due time", "D service time", "D ready time", "D due time"});
+      for (int i = 0; i < orders; i++) {
+        DynPDPParser.Order order = parser.Orders[i];
+
+        orderMatrix[i, 0] = order.revealedTime;
+        orderMatrix[i, 1] = order.pickupXCoord;
+        orderMatrix[i, 2] = order.pickupYCoord;
+        orderMatrix[i, 3] = order.deliveryXCoord;
+        orderMatrix[i, 4] = order.deliveryYCoord;
+        orderMatrix[i, 5] = order.demand;
+        orderMatrix[i, 6] = order.pickupServiceTime;
+        orderMatrix[i, 7] = order.pickupReadyTime;
+        orderMatrix[i, 8] = order.pickupDueTime;
+        orderMatrix[i, 9] = order.deliveryServiceTime;
+        orderMatrix[i, 10] = order.deliveryReadyTime;
+        orderMatrix[i, 11] = order.deliveryDueTime;
+      }
+      orderGen.OrdersParameter.Value = orderMatrix;
+      OrderGeneratorParameter.Value = orderGen;
+
+      OnScenarioChanged();
+    }
+
+    public void ImportFromDynPDP(string fileName) {
+      DefaultDynPDPParser parser = new DefaultDynPDPParser(fileName);
+      ImportFromDynPDP(parser);
+    }
+
+    public void ImportFromDynTSPLib(string fileName) {
+      TSPLibDynPDPParser parser = new TSPLibDynPDPParser(fileName);
+      ImportFromDynPDP(parser);
+    }
+
+    [StorableConstructor]
+    private PickupDeliveryScenario(bool deserializing) : base(deserializing) { }
+    private PickupDeliveryScenario(PickupDeliveryScenario original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PickupDeliveryScenario(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliverySimulation.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliverySimulation.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliverySimulation.cs	(revision 16099)
@@ -0,0 +1,607 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PDPSimulation.SimulationCore;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Optimization;
+using HeuristicLab.Analysis;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliverySimulation", "A pickup and delivery simulation.")]
+  [Creatable("Simulations")]
+  [StorableClass]
+  public sealed class PickupDeliverySimulation: Simulation {
+    #region parameters
+    public OptionalValueParameter<PickupDeliveryOptimization> OptimizationParameter {
+      get { return (OptionalValueParameter<PickupDeliveryOptimization>)Parameters["PickupDeliveryOptimization"]; }
+    }
+
+    public OptionalValueParameter<WaitingStrategy> WaitingStrategyParameter {
+      get { return (OptionalValueParameter<WaitingStrategy>)Parameters["WaitingStrategy"]; }
+    }
+
+    public OptionalValueParameter<PickupDeliveryAnalyzer> AnalyzerParameter {
+      get { return (OptionalValueParameter<PickupDeliveryAnalyzer>)Parameters["Analyzer"]; }
+    }
+
+    public ValueParameter<DoubleValue> TimeStepParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["TimeStep"]; }
+    }
+
+    public ValueParameter<DoubleValue> ResultCollectionIntervalParameter {
+      get { return (ValueParameter<DoubleValue>)Parameters["ResultCollectionInterval"]; }
+    }
+
+
+    public ValueParameter<BoolValue> SynchronizedParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["Synchronized"]; }
+    }
+    public ValueParameter<IntValue> DelayParameter {
+      get { return (ValueParameter<IntValue>)Parameters["Delay"]; }
+    }
+    public ValueParameter<IntValue> InitialDelayParameter {
+      get { return (ValueParameter<IntValue>)Parameters["InitialDelay"]; }
+    }
+
+    private ValueParameter<IntValue> SeedParameter {
+      get { return (ValueParameter<IntValue>)Parameters["Seed"]; }
+    }
+    private ValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["SetSeedRandomly"]; }
+    }
+    #endregion
+
+    #region properties
+    public double SimulationTime {
+      get {
+        return simulationTime;
+      }
+
+      private set {
+        simulationTime = value;
+      }
+    }
+
+    public double TimeStep {
+      get {
+        return TimeStepParameter.Value.Value;
+      }
+    }
+
+    private double ResultCollectionInterval {
+      get {
+        return ResultCollectionIntervalParameter.Value.Value;
+      }
+    }
+
+    private bool Synchronized {
+      get {
+        return SynchronizedParameter.Value.Value;
+      }
+    }
+
+    private int Delay {
+      get {
+        return DelayParameter.Value.Value;
+      }
+    }
+
+    public override Type ProblemType {
+      get { return typeof(PickupDeliveryScenario); }
+    }
+
+    private PickupDeliveryScenario Scenario {
+      get {
+        return Problem as PickupDeliveryScenario;
+      }
+    }
+
+    private PickupDeliveryOptimization Optimization {
+      get { return OptimizationParameter.Value;  }
+    }
+
+    private WaitingStrategy WaitingStrategy {
+      get { return WaitingStrategyParameter.Value; }
+    }
+
+    private PickupDeliveryAnalyzer Analyzer {
+      get { return AnalyzerParameter.Value; }
+    }
+    #endregion
+
+    #region constructors
+    public PickupDeliverySimulation()
+      : base() {
+      Parameters.Add(new OptionalValueParameter<PickupDeliveryOptimization>("PickupDeliveryOptimization", new BestInsertion()));
+      Parameters.Add(new OptionalValueParameter<WaitingStrategy>("WaitingStrategy", new DriveFirstWaitingStrategy()));
+      Parameters.Add(new OptionalValueParameter<PickupDeliveryAnalyzer>("Analyzer", new PickupDeliveryAnalyzer()));
+      Parameters.Add(new ValueParameter<DoubleValue>("TimeStep", "The time progress after every tick", new DoubleValue(1)));
+      Parameters.Add(new ValueParameter<DoubleValue>("ResultCollectionInterval", "The result collection interval", new DoubleValue(1)));
+      Parameters.Add(new ValueParameter<BoolValue>("Synchronized", "Indicates if the simulation and optimization should be synchronized", new BoolValue(true)));
+      Parameters.Add(new ValueParameter<IntValue>("Delay", "The delay after each tick", new IntValue(0)));
+      Parameters.Add(new ValueParameter<IntValue>("InitialDelay", "The initial delay", new IntValue(0)));
+      Parameters.Add(new ValueParameter<IntValue>("Seed", "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<BoolValue>("SetSeedRandomly", "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+
+      OptimizationParameter.GetsCollected = false;
+
+      orders = new List<Order>();
+      vehicles = new List<Vehicle>();
+
+      AttachEventHandlers();
+      SetOptimizationSimulation();
+      SetOptimizationScenario();
+      SetWaitingStrategy();
+      SetWaitingStrategyScenario();
+    }
+    [StorableConstructor]
+    private PickupDeliverySimulation(bool deserializing) : base(deserializing) {
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      AttachEventHandlers();
+    }
+
+    private PickupDeliverySimulation(PickupDeliverySimulation original, Cloner cloner)
+      : base(original, cloner) {
+      orders = new List<Order>();
+      foreach (Order order in original.orders) {
+        orders.Add(cloner.Clone<Order>(order));
+      }
+
+      vehicles = new List<Vehicle>();
+      foreach (Vehicle vehicle in original.vehicles) {
+        vehicles.Add(cloner.Clone<Vehicle>(vehicle));
+      }
+
+      simulationTime = original.simulationTime;
+      newSimulationTime = original.newSimulationTime;
+      lastResultCollection = original.lastResultCollection;
+      simulationObject = cloner.Clone<SimulationObject>(original.simulationObject);
+
+      AttachEventHandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PickupDeliverySimulation(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AttachEventHandlers() {
+      OptimizationParameter.ValueChanged += new EventHandler(OptimizationParameter_ValueChanged);
+      WaitingStrategyParameter.ValueChanged += new EventHandler(WaitingStrategyParameter_ValueChanged);
+
+      if(Scenario != null)
+        Scenario.ScenarioChanged += new EventHandler(Scenario_ScenarioChanged);
+    }
+
+    void Scenario_ScenarioChanged(object sender, EventArgs e) {
+      SetOptimizationScenario();
+      SetWaitingStrategy();
+      SetWaitingStrategyScenario();
+
+      Prepare();
+    }
+
+    void WaitingStrategyParameter_ValueChanged(object sender, EventArgs e) {
+      SetWaitingStrategy();
+      SetWaitingStrategyScenario();
+    }
+
+    void OptimizationParameter_ValueChanged(object sender, EventArgs e) {
+      SetOptimizationSimulation();
+      SetOptimizationScenario();
+      SetWaitingStrategy();
+    }
+
+    protected override void OnProblemChanged() {
+      base.OnProblemChanged();
+
+      SetOptimizationScenario();
+      SetWaitingStrategy();
+      SetWaitingStrategyScenario();
+
+      if (Scenario != null)
+        Scenario.ScenarioChanged += new EventHandler(Scenario_ScenarioChanged);
+    }
+    #endregion
+
+    #region state
+    [Storable]
+    private List<Order> orders;
+
+    public List<Order> Orders {
+      get {
+        lock (orders) {
+          return new List<Order>(orders);
+        }
+      }
+    }
+
+    public Order GetOrder(Guid orderId) {
+      lock (orders) {
+        return orders.FirstOrDefault(o => o.Id == orderId);
+      }
+    }
+
+    public double OrderRangeX {
+      get { return Scenario.OrderRangeX(); }
+    }
+
+    public double OrderRangeY {
+      get { return Scenario.OrderRangeY(); }
+    }
+
+    private bool AllOrdersDelivered() {
+      bool delivered = true;
+
+      foreach(Order order in orders) {
+        if (order.OrderState != OrderState.Delivered) {
+          delivered = false;
+          break;
+        }
+      }
+
+      return delivered;
+    }
+
+    [Storable]
+    private List<Vehicle> vehicles;
+
+    public List<Vehicle> Vehicles {
+      get {
+        return new List<Vehicle>(vehicles);
+      }
+    }
+
+    public Vehicle GetVehicle(Guid vehicleId) {
+      return vehicles.FirstOrDefault(v => v.Id == vehicleId);
+    }
+
+    private bool AllVehiclesAtDepot() {
+      bool atDepot = true;
+
+      foreach (Vehicle vehicle in vehicles) {
+        if ((vehicle.VehicleState != VehicleState.Parked && vehicle.VehicleState != VehicleState.Waiting) ||
+          vehicle.PositionX != vehicle.DepotX ||
+          vehicle.PositionY != vehicle.DepotY) {
+          atDepot = false;
+          break;
+        }
+      }
+
+      return atDepot;
+    }
+
+    public PDAction GetAction(Vehicle vehicle) {
+      if (Optimization != null)
+        return Optimization.GetAction(vehicle);
+      else
+        return null;
+    }
+
+    [Storable]
+    private double newSimulationTime;
+
+    [Storable]
+    private double simulationTime;
+
+    [Storable]
+    private double lastResultCollection;
+
+    [Storable]
+    private SimulationObject simulationObject;
+    #endregion
+
+    #region events
+
+    public delegate void SimulationStateChangedHandler(BaseObject obj, SimulationStateChange change);
+    public event SimulationStateChangedHandler SimulationStateChanged;
+
+    private void OnSimulationStateChanged(BaseObject obj, SimulationStateChange change) {
+      SimulationStateChangedHandler handler = SimulationStateChanged;
+      if (handler != null)
+        handler(obj, change);
+    }
+    #endregion
+
+    #region synchronization
+    private EventWaitHandle wh;
+    private void InitWaitHandle() {
+      if(wh != null)
+        wh.Dispose();
+
+      wh = null;
+      if (Synchronized)
+        wh = new EventWaitHandle(false, EventResetMode.AutoReset);
+    }
+    private void SignalWaitHandle() {
+      if (wh != null)
+        wh.Set();
+    }
+    public void WaitForSimulation() {
+      if (wh != null)
+        wh.WaitOne();
+    }
+    private void WaitForOptimization() {
+      if (Optimization != null)
+        Optimization.WaitForOptimization();
+    }
+    #endregion
+
+    #region simulation logic
+    private void UpdateVisualization() {
+      if (Analyzer != null)
+        Analyzer.UpdateVisualization(this, Scenario, Results);
+    }
+
+    private void UpdateSimulationState() {
+      if (Optimization != null) {
+        foreach (PDAction action in Optimization.GetActions()) {
+          BaseObject obj = vehicles.FirstOrDefault(v => v.Id == action.BaseObjectId);
+          if(obj == null)
+            obj = orders.FirstOrDefault(o => o.Id == action.BaseObjectId);
+
+          List<PDChange> changes = action.Perform(obj, SimulationTime, TimeStep);
+
+          foreach (PDChange change in changes)
+            OnSimulationStateChanged(change.BaseObject, change.ChangeType);
+        }
+      }
+    }
+
+    private void UpdateResults(bool stopped) {
+      if (stopped || SimulationTime == 0 ||
+         (SimulationTime - lastResultCollection) >= ResultCollectionInterval) {
+        UpdateVisualization();   
+        if (Analyzer != null) {
+          Analyzer.Analyze(this, Scenario, Results);
+        }
+
+        lastResultCollection = SimulationTime;
+      }
+      if (Analyzer != null) {
+        Analyzer.Tick(this, Scenario, Results);
+      }
+    }
+
+    private void UpdateOrders() {
+      lock (orders) {
+        IEnumerable<Order> newOrders = Scenario.GetOrders(SimulationTime, newSimulationTime);
+        foreach (Order order in newOrders) {
+          orders.Add(order);
+          OnSimulationStateChanged(order, SimulationStateChange.OrderCreated);
+        }
+
+        if (!Scenario.MoreOrders(newSimulationTime))
+          OnSimulationStateChanged(simulationObject, SimulationStateChange.NoMoreOrders);
+      }
+    }
+
+    private void CreateSimulation() {
+      vehicles.Clear();
+      orders.Clear();
+
+      simulationObject = new SimulationObject();
+      lastResultCollection = 0;
+      simulationTime = 0;
+      newSimulationTime = 0;
+
+      //create vehicles
+      for (int i = 0; i < Scenario.VehicleCapacitiesParameter.Value.Length; i++) {
+        Vehicle v = new Vehicle();
+        v.VehicleState = VehicleState.Parked;
+        v.Availibility = 1;
+        v.DepotX = v.PositionX = v.TargetPositionX = Scenario.DepotCoordinatesParameter.Value[i, 0];
+        v.DepotY = v.PositionY = v.TargetPositionY = Scenario.DepotCoordinatesParameter.Value[i, 1];
+        v.Capacity = v.TotalCapacity = Scenario.VehicleCapacitiesParameter.Value[i];
+        v.ReadyTime = Scenario.VehicleReadyTimesParameter.Value[i];
+        v.DueTime = Scenario.VehicleDueTimesParameter.Value[i];
+
+        vehicles.Add(v);
+        OnSimulationStateChanged(v, SimulationStateChange.VehicleCreated);
+      }
+
+      //create initial orders
+      UpdateOrders();
+      UpdateResults(false);
+
+      UpdateVisualization();
+    }
+
+    protected override void OnPrepared() {
+      base.OnPrepared();
+      PrepareOptimization();
+      simulationTime = 0;
+      newSimulationTime = 0;
+    }
+
+    private void InitSimulation() {
+      pausePending = false;
+      stopPending = false;
+      InitWaitHandle();
+
+      if (simulationTime == 0) {
+        PrepareOptimization();
+        CreateSimulation();
+
+        SignalWaitHandle();
+        if (OptimizationRequired()) {
+          StartOptimization();
+          Thread.Sleep(InitialDelayParameter.Value.Value);
+          WaitForOptimization();
+        } else {
+          Thread.Sleep(InitialDelayParameter.Value.Value);
+        }
+
+        Step();
+      }
+    }
+
+    private void StartOptimization() {
+      if (Optimization != null) {
+        Optimization.Start(Synchronized);
+      }
+    }
+
+    private void StopOptimization() {
+      if (Optimization != null)
+        Optimization.Stop();
+    }
+
+    private void PrepareOptimization() {
+      if (Optimization != null)
+        Optimization.Prepare();
+    }
+
+    private void SetOptimizationScenario() {
+      if (Optimization != null)
+        Optimization.SetScenario(Scenario);
+    }
+
+    private void SetOptimizationSimulation() {
+      if (Optimization != null)
+        Optimization.SetSimulation(this);
+    }
+
+    private void SetWaitingStrategyScenario() {
+      if (WaitingStrategy != null)
+        WaitingStrategy.SetScenario(Scenario);
+    }
+
+    private void SetWaitingStrategy() {
+      if (Optimization != null)
+        Optimization.SetWaitingStrategy(WaitingStrategyParameter.Value);
+    }
+
+    private bool OptimizationRunning() {
+      bool running = false;
+
+      if (Optimization != null)
+        running = Optimization.Running();
+
+      return running;
+    }
+
+    private void RelocateVehicles() {
+      if (Optimization != null)
+        Optimization.RelocateVehicles();
+    }
+
+    private bool OptimizationRequired() {
+      bool required = false;
+
+      if (Optimization != null)
+        required = Optimization.OptimizationRequired();
+
+      return required;
+    }
+
+    private void WaitForOptimizationExit() {
+      if (Optimization != null) {
+        while (Optimization.Running()) {
+          Thread.Sleep(100);
+          SignalWaitHandle();
+        }
+        Optimization.Exit();
+      }
+    }
+
+    private void StopSimulation() {
+      SignalWaitHandle();
+      StopOptimization();
+    }
+
+    private bool pausePending;
+    public override void Pause() {
+      base.Pause();
+      pausePending = true;
+    }
+
+    private bool stopPending;
+    public override void Stop() {
+      base.Stop();
+      stopPending = true;
+    }
+
+    private void Step() {
+      //next step
+      SimulationTime = newSimulationTime;
+      newSimulationTime = SimulationTime + TimeStep;
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      InitSimulation();
+
+      while (!AllOrdersDelivered() || Scenario.MoreOrders(SimulationTime) || (Scenario.RelocateBackToDepot && !AllVehiclesAtDepot())) {
+        //perform actions
+        UpdateSimulationState();
+        UpdateOrders();
+        UpdateResults(false);
+
+        Step();
+
+        if (OptimizationRequired()) {
+          SignalWaitHandle();
+
+          if (!OptimizationRunning() && !(pausePending || stopPending)) {
+            SignalWaitHandle();
+            StartOptimization();
+          }
+
+          WaitForOptimization();
+        } else {
+          RelocateVehicles();
+        }
+
+        if (pausePending || stopPending) {
+          if (!OptimizationRunning()) {
+            cancellationToken.ThrowIfCancellationRequested();
+          } else
+            StopOptimization();
+        }
+
+        Thread.Sleep(Delay);
+      }
+
+      if (Optimization != null)
+        Optimization.RemoveCompletedActions();
+      UpdateResults(true);
+
+      Results.Add(new Result("Finished", new BoolValue(true)));
+
+      Thread.Sleep(500);
+      StopSimulation();
+      WaitForOptimizationExit();
+    }
+  }
+  #endregion
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryVisualization.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryVisualization.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/PickupDeliveryVisualization.cs	(revision 16099)
@@ -0,0 +1,132 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("PickupDeliveryVisualization", "Represents an PDP scenario visualization.")]
+  [StorableClass]
+  public class PickupDeliveryVisualization : Item {
+    [Storable]
+    private List<Order> orders;
+    public IEnumerable<Order> Orders {
+      get { return orders; }
+    }
+
+    [Storable]
+    private double orderRangeX;
+    public double OrderRangeX {
+      get { return orderRangeX; }
+    }
+
+    [Storable]
+    private double orderRangeY;
+    public double OrderRangeY {
+      get { return orderRangeY; }
+    }
+
+    [Storable]
+    private List<Vehicle> vehicles;
+    public IEnumerable<Vehicle> Vehicles {
+      get { return vehicles; }
+    }
+
+    [Storable]
+    private Dictionary<Vehicle, PDAction> actions;
+    public PDAction GetAction(Vehicle vehicle) {
+      if (actions.ContainsKey(vehicle))
+        return actions[vehicle];
+      else
+        return null;
+    }
+
+    public void SetState(PickupDeliverySimulation simulation) {
+      orders = new List<Order>();
+      foreach (Order order in simulation.Orders) {
+        orders.Add(order.Clone() as Order);
+      }
+
+      orderRangeX = simulation.OrderRangeX;
+      orderRangeY = simulation.OrderRangeY;
+
+      vehicles = new List<Vehicle>();
+      actions = new Dictionary<Vehicle, PDAction>();
+      foreach (Vehicle vehicle in simulation.Vehicles) {
+        Vehicle clone = vehicle.Clone() as Vehicle;
+        vehicles.Add(clone);
+        PDAction action = simulation.GetAction(vehicle);
+        if (action != null)
+          actions[clone] = action.Clone() as PDAction;
+      }
+    }
+
+    public PickupDeliveryVisualization(PickupDeliverySimulation simulation)
+      : base() {
+      SetState(simulation);      
+    }
+
+    [StorableConstructor]
+    protected PickupDeliveryVisualization(bool deserializing) : base(deserializing) { }
+    protected PickupDeliveryVisualization(PickupDeliveryVisualization original, Cloner cloner)
+      : base(original, cloner) {
+      orders = new List<Order>();
+      foreach (Order order in original.orders) {
+        orders.Add(order.Clone() as Order);
+      }
+
+      orderRangeX = original.orderRangeX;
+      orderRangeY = original.orderRangeY;
+
+      vehicles = new List<Vehicle>();
+      actions = new Dictionary<Vehicle, PDAction>();
+      foreach (Vehicle vehicle in original.vehicles) {
+        Vehicle clone = vehicle.Clone() as Vehicle;
+        vehicles.Add(clone);
+        PDAction action = original.GetAction(vehicle);
+        if (action != null)
+          actions[clone] = action.Clone() as PDAction;
+      }   
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PickupDeliveryVisualization(this, cloner);
+    }
+
+    public event EventHandler ContentChanged;
+    private void OnContentChanged() {
+      var changed = ContentChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public void Refresh() {
+      OnContentChanged();
+    }
+  }
+}
+
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Plugin.cs.frame
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Plugin.cs.frame	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Plugin.cs.frame	(revision 16099)
@@ -0,0 +1,53 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.PDPSimulation {
+  /// <summary>
+  /// Plugin class for HeuristicLab.PDPSimulation plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.PDPSimulation", "3.3.4.$WCREV$")]
+  [PluginFile("HeuristicLab.PDPSimulation-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.PermutationEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding", "3.4")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.VehicleRouting", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis.Symbolic", "3.4")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabPDPSimulationPlugin : PluginBase {
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Properties/AssemblyInfo.cs.frame	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Properties/AssemblyInfo.cs.frame	(revision 16099)
@@ -0,0 +1,56 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.PDPSimulation")]
+[assembly: AssemblyDescription("HeuristicLab pickup and delivery simulation")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2011 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1A1B1495-36DD-4EE5-ACAA-0490EE333D13")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.4.$WCREV$")]
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/IScenario.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/IScenario.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/IScenario.cs	(revision 16099)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.PDPSimulation.SimulationCore {
+  public interface IScenario : IProblem {
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/ISimulation.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/ISimulation.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/ISimulation.cs	(revision 16099)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.PDPSimulation.SimulationCore {
+  public interface ISimulation: IAlgorithm {
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Scenario.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Scenario.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Scenario.cs	(revision 16099)
@@ -0,0 +1,51 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation.SimulationCore {
+  [Item("Scenario", "Represents the base class for a simulation scenario.")]
+  [StorableClass]
+  public abstract class Scenario : ParameterizedNamedItem, IScenario  {
+    [StorableConstructor]
+    protected Scenario(bool deserializing) : base(deserializing) { }
+    protected Scenario(Scenario original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    protected Scenario() : base() {}
+
+    #region IProblem Members
+    public IEnumerable<IItem> Operators {
+      get { return null; }
+    }
+    
+    public event EventHandler OperatorsChanged;
+    public event EventHandler Reset;
+    #endregion
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Simulation.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Simulation.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationCore/Simulation.cs	(revision 16099)
@@ -0,0 +1,185 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using System.Drawing;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.Collections;
+using HeuristicLab.Optimization;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.PDPSimulation.SimulationCore {
+  [Item("Simulation", "A base class for simulations.")]
+  [StorableClass]
+  public abstract class Simulation: Algorithm, ISimulation, IStorableContent {
+    public string Filename { get; set; }
+        
+    public override Type ProblemType {
+      get { return typeof(IScenario); }
+    }
+
+    [Storable]
+    private ResultCollection results;
+    public override ResultCollection Results {
+      get {
+        return results;
+      }
+    }
+
+    #region Variables for communication between threads
+    private CancellationTokenSource cancellationTokenSource;
+    private bool stopPending;
+    private DateTime lastUpdateTime;
+    #endregion
+
+    [StorableConstructor]
+    protected Simulation(bool deserializing) : base(deserializing) { }
+    protected Simulation()
+      : base() {
+        results = new ResultCollection();
+    }
+    protected Simulation(Simulation original, Cloner cloner)
+      : base(original, cloner) {
+        results = cloner.Clone(original.results) as ResultCollection;
+    }
+
+    public sealed override void Prepare() {
+      base.Prepare();
+      results.Clear();
+      OnPrepared();
+    }
+    protected override void OnPrepared() {
+      base.OnPrepared();
+    }
+
+    private class RunInformation {
+      public CancellationTokenSource CancellationToken { get; set; }
+      public IExecutionContext ExecutionContext { get; set; }
+    }
+
+    public virtual void Start(IExecutionContext executionContext) {
+      base.Start();
+
+      RunInformation runInfo = new RunInformation();
+      cancellationTokenSource = new CancellationTokenSource();
+      runInfo.CancellationToken = cancellationTokenSource;
+      runInfo.ExecutionContext = executionContext;
+      stopPending = false;
+      Task task = Task.Factory.StartNew(Run, runInfo, runInfo.CancellationToken.Token);
+      task.ContinueWith(t => {
+        try {
+          t.Wait();
+        }
+        catch (AggregateException ex) {
+          try {
+            ex.Flatten().Handle(x => x is OperationCanceledException);
+          }
+          catch (AggregateException remaining) {
+            if (remaining.InnerExceptions.Count == 1) OnExceptionOccurred(remaining.InnerExceptions[0]);
+            else OnExceptionOccurred(remaining);
+          }
+        }
+        cancellationTokenSource.Dispose();
+        cancellationTokenSource = null;
+        if (stopPending) OnStopped();
+        else OnPaused();
+      });
+    }
+
+    public override void Start() {
+      Start(null);      
+    }
+    protected override void OnStarted() {
+      base.OnStarted();
+    }
+
+    public override void Pause() {
+      base.Pause();
+      cancellationTokenSource.Cancel();
+    }
+    protected override void OnPaused() {
+      base.OnPaused();
+    }
+
+    public override void Stop() {
+      base.Stop();
+      if (ExecutionState == ExecutionState.Paused) {
+        OnStopped();
+      } else {
+        stopPending = true;
+        cancellationTokenSource.Cancel();
+      }
+    }
+    protected override void OnStopped() {
+      base.OnStopped();
+    }
+
+    protected override void OnExceptionOccurred(Exception exception) {
+      base.OnExceptionOccurred(exception);
+    }
+
+    private void Run(object state) {
+      RunInformation runInfo = (RunInformation)state;
+
+      OnStarted();
+      lastUpdateTime = DateTime.Now;
+      System.Timers.Timer timer = new System.Timers.Timer(250);
+      timer.AutoReset = true;
+      timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
+      timer.Start();
+      try {
+        foreach (IParameter parameter in Parameters) {
+          parameter.ExecutionContext = runInfo.ExecutionContext;
+        }
+
+        Run(runInfo.CancellationToken.Token);
+      }
+      finally {
+        timer.Elapsed -= new System.Timers.ElapsedEventHandler(timer_Elapsed);
+        timer.Stop();
+        ExecutionTime += DateTime.Now - lastUpdateTime;
+
+        foreach (IParameter parameter in Parameters) {
+          parameter.ExecutionContext = null;
+        }
+      }
+      Stop();
+
+      runInfo.CancellationToken.Token.ThrowIfCancellationRequested();
+    }
+    protected abstract void Run(CancellationToken cancellationToken);
+
+    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) {
+      System.Timers.Timer timer = (System.Timers.Timer)sender;
+      timer.Enabled = false;
+      DateTime now = DateTime.Now;
+      ExecutionTime += now - lastUpdateTime;
+      lastUpdateTime = now;
+      timer.Enabled = true;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/MoveVehicleAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/MoveVehicleAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/MoveVehicleAction.cs	(revision 16099)
@@ -0,0 +1,375 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.PDPSimulation {
+  public enum VehicleAction { Wait, Pickup, Deliver, Park, Invalid }
+
+  [StorableClass]
+  public class MoveVehicleAction : PDAction {
+    [Storable]
+    double sourceX;
+
+    public double SourceX {
+      get { return sourceX; }
+    }
+
+    [Storable]
+    double sourceY;
+
+    public double SourceY {
+      get { return sourceY; }
+    }
+
+    [Storable]
+    double targetX;
+
+    public double TargetX {
+      get { return targetX; }
+    }
+
+    [Storable]
+    double targetY;
+
+    public double TargetY {
+      get { return targetY; }
+    }
+
+    [Storable]
+    VehicleAction action;
+
+    [Storable]
+    Order order;
+
+    [Storable]
+    double serviceTime;
+
+    [Storable]
+    bool interruptable;
+
+    [Storable]
+    bool completed;
+
+    [Storable]
+    DistanceMeasure distMeasure;
+
+    [Storable]
+    bool diversionAllowed;
+
+    public MoveVehicleAction(
+      Guid vehicleId,
+      double targetX, double targetY, VehicleAction action, Order order, bool diversionAllowed, DistanceMeasure distMeasure)
+      : base(vehicleId) {
+      this.targetX = targetX;
+      this.targetY = targetY;
+      this.action = action;
+      this.order = order;
+      this.serviceTime = 0;
+      this.completed = false;
+      this.diversionAllowed = diversionAllowed;
+      this.interruptable = diversionAllowed;
+      this.distMeasure = distMeasure;
+
+      this.sourceX = -1;
+      this.sourceY = -1;
+    }
+    [StorableConstructor]
+    protected MoveVehicleAction(bool deserializing)
+      : base(deserializing) {
+    }
+    protected MoveVehicleAction(MoveVehicleAction original, Cloner cloner)
+      : base(original, cloner) {
+      this.targetX = original.targetX;
+      this.sourceX = original.sourceX;
+      this.targetY = original.targetY;
+      this.sourceY = original.sourceY;
+      this.action = original.action;
+      this.order = cloner.Clone<Order>(original.order);
+      this.serviceTime = original.serviceTime;
+      this.completed = original.completed;
+      this.interruptable = original.interruptable;
+      this.distMeasure = cloner.Clone<DistanceMeasure>(original.distMeasure);
+      this.diversionAllowed = original.diversionAllowed;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MoveVehicleAction(this, cloner);
+    }
+
+    protected override bool ActionInterruptable() {
+      return interruptable;
+    }
+
+    public override bool ActionCompleted() {
+      return completed;
+    }
+
+    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
+      Vehicle vehicle = baseObject as Vehicle;
+      lock (vehicle) {
+        if ((action == VehicleAction.Pickup && (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp)) ||
+            (action == VehicleAction.Deliver && ((order.ServiceRequest && order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp) ||
+                                                 (!order.ServiceRequest && ((order.OrderState != OrderState.PickedUp && order.OrderState != OrderState.Delivering) || !vehicle.PickedUpOrders.Contains(order.Id))))) ||
+           (order != null && (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id))) {
+          if (vehicle.VehicleState != VehicleState.InvalidAction) {
+            vehicle.InvalidActions++;
+
+            vehicle.VehicleState = VehicleState.InvalidAction;
+            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+          }
+
+          if (diversionAllowed)
+            vehicle.ReadyTime = simulationTime;
+          interruptable = diversionAllowed;
+          completed = diversionAllowed;
+
+          if (diversionAllowed)
+            return simulationTime;
+          else {
+            if (order != null) {
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderFailed, BaseObject = order });
+              order = null;
+              action = VehicleAction.Invalid;
+            }
+          }
+        }
+
+        if (sourceX == -1) {
+          sourceX = vehicle.PositionX;
+          sourceY = vehicle.PositionY;
+        }
+
+        vehicle.TargetPositionX = targetX;
+        vehicle.TargetPositionY = targetY;
+        vehicle.CurrentAction = action;
+        if (order == null)
+          vehicle.CurrentOrder = Guid.Empty;
+        else {
+          if (!diversionAllowed)
+            order.Vehicle = vehicle.Id;
+          vehicle.CurrentOrder = order.Id;
+          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+        }
+
+        if (action == VehicleAction.Wait || action == VehicleAction.Park)
+          if (diversionAllowed)
+            vehicle.ReadyTime = simulationTime;
+
+        double tx, ty, length;
+        distMeasure.Move(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY, tickTime, vehicle.MoveInfo,
+          out tx, out ty, out length);
+
+        if (!diversionAllowed) {
+          double time = simulationTime;
+          time += distMeasure.GetDistance(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY);
+          if (action == VehicleAction.Pickup) {
+            if (time < order.PickupReadyTime)
+              time = order.PickupReadyTime;
+
+            time += order.PickupServiceTime - serviceTime;
+          } else if (action == VehicleAction.Deliver) {
+            if (time < order.DeliveryReadyTime)
+              time = order.DeliveryReadyTime;
+
+            time += order.DeliveryServiceTime - serviceTime;
+          }
+
+          vehicle.ReadyTime = time;
+        }
+
+        vehicle.PositionX = tx;
+        vehicle.PositionY = ty;
+
+        if (length > 0) {
+          vehicle.Distance += length;
+          tickTime -= length;
+          simulationTime += length;
+
+          if (vehicle.VehicleState != VehicleState.Moving) {
+            vehicle.VehicleState = VehicleState.Moving;
+            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+          }
+          changes.Add(
+            new PDChange() { ChangeType = SimulationStateChange.VehicleMoved, BaseObject = baseObject });
+        }
+
+        if (vehicle.PositionX == targetX && vehicle.PositionY == targetY) {
+          if (action == VehicleAction.Pickup || (action == VehicleAction.Deliver && order.ServiceRequest)) {
+            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
+              throw new Exception("Order already assigned");
+
+            if (simulationTime < order.PickupReadyTime) {
+              if (vehicle.VehicleState != VehicleState.Waiting) {
+                if (diversionAllowed)
+                  vehicle.ReadyTime = simulationTime;
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                interruptable = diversionAllowed;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              double waitTime = Math.Min(tickTime,
+                order.PickupReadyTime - simulationTime);
+
+              simulationTime += waitTime;
+              tickTime -= waitTime;
+            }
+
+            //pickup
+            if (simulationTime >= order.PickupReadyTime &&
+              tickTime > 0) {
+              if (vehicle.VehicleState != VehicleState.Servicing) {
+                if (diversionAllowed) {
+                  vehicle.ReadyTime = simulationTime;
+                  vehicle.ReadyTime += order.PickupServiceTime;
+                }
+
+                vehicle.VehicleState = VehicleState.Servicing;
+                interruptable = false;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              if (order.OrderState != OrderState.PickingUp) {
+                order.PickupTime = simulationTime;
+                order.Vehicle = vehicle.Id;
+                order.OrderState = OrderState.PickingUp;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                if (simulationTime > order.PickupDueTime) {
+                  order.Tardiness += simulationTime - order.PickupDueTime;
+                }
+              }
+
+              double service = Math.Min(tickTime,
+                order.PickupServiceTime - serviceTime);
+
+              serviceTime += service;
+              simulationTime += service;
+              tickTime -= service;
+
+              //load
+              if (serviceTime == order.PickupServiceTime) {
+                vehicle.Capacity -= order.Demand;
+
+                if (vehicle.Capacity < 0) {
+                  vehicle.Overload += -vehicle.Capacity;
+                  vehicle.Capacity = 0;
+                }
+
+                vehicle.PickedUpOrders.Add(order.Id);
+                order.Vehicle = vehicle.Id;
+                if (order.ServiceRequest)
+                  order.OrderState = OrderState.Delivered;
+                else
+                  order.OrderState = OrderState.PickedUp;
+                vehicle.CurrentOrder = Guid.Empty;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+                completed = true;
+              }
+            }
+          } else if (action == VehicleAction.Deliver) {
+            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
+              throw new Exception("Order already assigned");
+
+            if (simulationTime < order.DeliveryReadyTime) {
+              if (vehicle.VehicleState != VehicleState.Waiting) {
+                if (diversionAllowed)
+                  vehicle.ReadyTime = simulationTime;
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                interruptable = diversionAllowed;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              double waitTime = Math.Min(tickTime,
+                order.DeliveryReadyTime - simulationTime);
+
+              simulationTime += waitTime;
+              tickTime -= waitTime;
+            }
+
+            //deliver
+            if (simulationTime >= order.DeliveryReadyTime &&
+              tickTime > 0) {
+              if (vehicle.VehicleState != VehicleState.Servicing) {
+                if (diversionAllowed) {
+                  vehicle.ReadyTime = simulationTime;
+                  vehicle.ReadyTime += order.DeliveryServiceTime;
+                }
+
+                vehicle.VehicleState = VehicleState.Servicing;
+                interruptable = false;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              if (order.OrderState != OrderState.Delivering) {
+                order.DeliveryTime = simulationTime;
+                order.OrderState = OrderState.Delivering;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                if (simulationTime > order.DeliveryDueTime) {
+                  order.Tardiness += simulationTime - order.DeliveryDueTime;
+                }
+              }
+
+              double service = Math.Min(tickTime,
+                order.DeliveryServiceTime - serviceTime);
+
+              serviceTime += service;
+              simulationTime += service;
+              tickTime -= service;
+
+              //load
+              if (serviceTime == order.DeliveryServiceTime) {
+                vehicle.Capacity += order.Demand;
+                vehicle.PickedUpOrders.Remove(order.Id);
+                order.OrderState = OrderState.Delivered;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                vehicle.CurrentOrder = Guid.Empty;
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+                completed = true;
+              }
+            }
+          } else if (action == VehicleAction.Park) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.Parked) {
+              vehicle.VehicleState = VehicleState.Parked;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+
+              if (vehicle.PositionX == vehicle.DepotX && vehicle.PositionY == vehicle.DepotY) {
+                if (simulationTime > vehicle.DueTime) {
+                  vehicle.Tardiness = simulationTime - vehicle.DueTime;
+                }
+              }
+            }
+          } else if (action == VehicleAction.Wait) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.Waiting) {
+              vehicle.VehicleState = VehicleState.Waiting;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+            }
+          } else if (action == VehicleAction.Invalid) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.InvalidAction) {
+              vehicle.VehicleState = VehicleState.InvalidAction;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+            }
+          }
+        }
+
+        return simulationTime;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDAction.cs	(revision 16099)
@@ -0,0 +1,134 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation {
+  [StorableClass]
+  public abstract class PDAction: Item {
+    [Storable]
+    private Guid baseObjectId;
+
+    public Guid BaseObjectId {
+      get { return baseObjectId; }
+    }
+
+    [Storable]
+    protected PDAction successor;
+
+    public PDAction Successor {
+      get { return successor; }
+    }
+
+    [Storable]
+    protected bool started;
+
+    public void AppendAction(PDAction action, bool recursive) {
+      if (!action.BaseObjectId.Equals(this.BaseObjectId))
+        throw new Exception("Can only append actions of the same object");
+      
+      PDAction predecessor = this;
+      while (predecessor.successor != null && 
+            (recursive || predecessor.ActionCompleted()))
+        predecessor = predecessor.successor;
+
+      predecessor.successor = action;
+    }
+
+    public bool IsCompleted {
+      get {
+        return ActionCompleted() &&
+          (successor == null || successor.IsCompleted);
+      }
+    }
+
+    protected abstract bool ActionInterruptable();
+
+    public bool Interruptable() {
+      PDAction action = this;
+
+      while (action != null && action.ActionCompleted())
+        action = action.successor;
+
+      return action == null || !action.started || action.ActionInterruptable();
+    }
+
+    public abstract bool ActionCompleted();
+
+    protected abstract double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes);
+
+    public List<PDChange> Perform(BaseObject baseObject, double simulationTime, double timeStep) {
+      List<PDChange> changes = new List<PDChange>();
+
+      lock (this) {
+        double startTime = simulationTime;
+
+        double tickTime = timeStep;
+        bool complete = ActionCompleted();
+        if (!complete && tickTime > 0) {
+          started = true;
+          simulationTime = Perform(baseObject, simulationTime, tickTime, changes);
+          complete = ActionCompleted();
+        }
+
+        PDAction next = successor;
+        while (complete && next != null) {
+          tickTime = timeStep - (simulationTime - startTime);
+
+          complete = next.ActionCompleted();
+          if (!complete && tickTime > 0) {
+            next.started = true;
+            simulationTime = next.Perform(baseObject, simulationTime, tickTime, changes);
+            complete = next.ActionCompleted();
+          }
+
+          next = next.successor;
+        }
+      }
+
+      return changes;
+    }
+
+    public virtual bool Obsoletes(PDAction action) {
+      return this.BaseObjectId.Equals(action.BaseObjectId);
+    }
+
+    protected PDAction(Guid baseObjectId) {
+      this.baseObjectId = baseObjectId;
+    }
+
+    [StorableConstructor]
+    protected PDAction(bool deserializing) : base(deserializing) { }
+    protected PDAction(PDAction original, Cloner cloner)
+      : base(original, cloner) {
+        baseObjectId = original.baseObjectId;
+        successor = cloner.Clone<PDAction>(original.successor);
+        started = original.started;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDChange.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDChange.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/PDChange.cs	(revision 16099)
@@ -0,0 +1,35 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation {
+  public enum SimulationStateChange { OrderCreated, OrderState, OrderFailed, VehicleCreated, VehicleMoved, VehicleState, VehicleAvailability, NoMoreOrders }
+  
+  [StorableClass]
+  public class PDChange : Item {
+    [Storable]
+    public BaseObject BaseObject { get; set; }
+
+    [Storable]
+    public SimulationStateChange ChangeType { get; set; }
+
+    public PDChange() {
+    }
+
+    [StorableConstructor]
+    protected PDChange(bool deserializing) : base(deserializing) { }
+    protected PDChange(PDChange original, Cloner cloner)
+      : base(original, cloner) {
+        BaseObject = cloner.Clone<BaseObject>(original.BaseObject);
+        ChangeType = original.ChangeType;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PDChange(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/WaitAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/WaitAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/SimulationModel/WaitAction.cs	(revision 16099)
@@ -0,0 +1,57 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+
+namespace HeuristicLab.PDPSimulation {  
+  [StorableClass]
+  public class WaitAction: PDAction {    
+    [Storable]
+    double waitingTime;
+
+    public WaitAction(Guid vehicleId, double waitingTime)
+      : base(vehicleId) {
+        this.waitingTime = waitingTime;
+    }
+    [StorableConstructor]
+    protected WaitAction(bool deserializing) : base(deserializing) {
+    }
+    protected WaitAction(WaitAction original, Cloner cloner)
+      : base(original, cloner) {
+        this.waitingTime = original.waitingTime;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WaitAction(this, cloner);
+    }
+
+    protected override bool ActionInterruptable() {
+      return true;
+    }
+
+    public override bool ActionCompleted() {
+      return waitingTime <= double.Epsilon;
+    }
+
+    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
+      double time = Math.Min(tickTime, waitingTime);
+      waitingTime -= time;
+
+      simulationTime += time;
+
+      Vehicle vehicle = baseObject as Vehicle;
+      lock (vehicle) {
+        if ((time > 0) && (vehicle.VehicleState != VehicleState.Waiting) && (vehicle.VehicleState != VehicleState.Parked)) {
+          vehicle.ReadyTime = 0;
+          vehicle.VehicleState = VehicleState.Waiting;
+          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+        }
+      }
+
+      return simulationTime;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/VehicleHistoryVisualization.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/VehicleHistoryVisualization.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/VehicleHistoryVisualization.cs	(revision 16099)
@@ -0,0 +1,92 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation {
+  [StorableClass]
+  public class VehicleHistory: Item {
+    [Storable]
+    public string VehicleName { get; private set; }
+    [Storable]
+    public List<VehicleState> VehicleState { get; private set; }
+    [Storable]
+    public List<int> VehicleAvailability { get; private set; }
+    [Storable]
+    public List<string> AvailabilityInformation { get; private set; }
+    [Storable]
+    public List<Order> ActiveOrders { get; private set; }
+    [Storable]
+    public List<Order> AssignedOrders { get; private set; }
+
+    public VehicleHistory(string vehicleName) {
+      VehicleName = vehicleName;
+      VehicleState = new List<VehicleState>();
+      VehicleAvailability = new List<int>();
+      AvailabilityInformation = new List<string>();
+      ActiveOrders = new List<Order>();
+      AssignedOrders = new List<Order>();
+    }
+     [StorableConstructor]
+    private VehicleHistory(bool deserializing) : base(deserializing) {
+    }
+     private VehicleHistory(VehicleHistory original, Cloner cloner)
+      : base(original, cloner) {
+        VehicleName = original.VehicleName;
+        VehicleState = new List<VehicleState>(original.VehicleState);
+        AvailabilityInformation = new List<string>(original.AvailabilityInformation);
+        ActiveOrders = new List<Order>();
+        foreach (Order order in original.ActiveOrders)
+          ActiveOrders.Add(cloner.Clone<Order>(order));
+        AssignedOrders = new List<Order>();
+        foreach (Order order in original.AssignedOrders)
+          AssignedOrders.Add(cloner.Clone<Order>(order));
+        VehicleAvailability = new List<int>();
+        VehicleAvailability.AddRange(original.VehicleAvailability);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VehicleHistory(this, cloner);
+    }
+  }
+
+  [StorableClass]
+  public class VehicleHistoryVisualization: Item {
+    [Storable]
+    public double ResultCollectionInterval { get; set; }
+    
+    [Storable]
+    public List<VehicleHistory> VehicleHistory { get; private set; }
+
+    public VehicleHistoryVisualization() {
+      VehicleHistory = new List<VehicleHistory>();
+      ResultCollectionInterval = 1.0;
+    }
+    [StorableConstructor]
+    protected VehicleHistoryVisualization(bool deserializing) : base(deserializing) {
+    }
+    protected VehicleHistoryVisualization(VehicleHistoryVisualization original, Cloner cloner)
+      : base(original, cloner) {
+        VehicleHistory = new List<VehicleHistory>();
+        foreach (VehicleHistory history in original.VehicleHistory) {
+          VehicleHistory.Add(cloner.Clone<VehicleHistory>(history));
+        } 
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VehicleHistoryVisualization(this, cloner);
+    }
+    public event EventHandler ContentChanged;
+    private void OnContentChanged() {
+      var changed = ContentChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    public void Refresh() {
+      OnContentChanged();
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/DriveFirstWaitingStrategy.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/DriveFirstWaitingStrategy.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/DriveFirstWaitingStrategy.cs	(revision 16099)
@@ -0,0 +1,66 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("DriveFirstWaitingStrategy", "A pickup and delivery waiting strategy.")]
+  [StorableClass]
+  public class DriveFirstWaitingStrategy : WaitingStrategy {
+    public ValueParameter<BoolValue> WaitAtSourceParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["WaitAtSource"]; }
+    }
+
+    public DriveFirstWaitingStrategy()
+      : base() {
+        Parameters.Add(new ValueParameter<BoolValue>("WaitAtSource", "Indicates, if waiting should only occur at the source and not the target.", new BoolValue(true)));
+    }
+    [StorableConstructor]
+    protected DriveFirstWaitingStrategy(bool deserializing) : base(deserializing) { }
+    protected DriveFirstWaitingStrategy(DriveFirstWaitingStrategy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DriveFirstWaitingStrategy(this, cloner);
+    }
+
+    public override double GetWaitingTime(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) {
+      bool waitAtSource = WaitAtSourceParameter.Value.Value;
+
+      if (waitAtSource) {
+        double waitTime = 0;
+
+        int vehicle = solution.GetVehicleAssignment(solution.GetTourIndex(tour));
+        bool moving = instance.VehicleStates[vehicle] == DomainModel.VehicleState.Moving;
+        if (!moving || stop != 0) {
+          int customer = 0;
+          if (stop < tour.Stops.Count)
+            customer = tour.Stops[stop];
+          int prev = 0;
+          if (stop > 0)
+            prev = tour.Stops[stop - 1];
+
+          if (customer > 0) {
+            time += instance.GetDistance(prev, customer, solution);
+            double readyTime = instance.ReadyTime[customer + instance.Depots.Value - 1];
+            if (time < readyTime) {
+              waitTime = readyTime - time;
+            }
+          }
+        }
+
+        return waitTime;
+      } else {
+        return 0;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/MoveVehicleAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/MoveVehicleAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/MoveVehicleAction.cs	(revision 16099)
@@ -0,0 +1,368 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+
+namespace HeuristicLab.PDPSimulation {
+  public enum VehicleAction { Wait, Pickup, Deliver, Park, Invalid }  
+  
+  [StorableClass]
+  public class MoveVehicleAction: PDAction {    
+    [Storable]
+    double sourceX;
+
+    public double SourceX {
+      get { return sourceX; }
+    }
+
+    [Storable]
+    double sourceY;
+
+    public double SourceY {
+      get { return sourceY; }
+    }
+    
+    [Storable]
+    double targetX;
+
+    public double TargetX {
+      get { return targetX; }
+    }
+
+    [Storable]
+    double targetY;
+
+    public double TargetY {
+      get { return targetY; }
+    }
+
+    [Storable]
+    VehicleAction action;
+
+    [Storable]
+    Order order;
+
+    [Storable]
+    double serviceTime;
+
+    [Storable]
+    bool interruptable;
+
+    [Storable]
+    bool completed;
+
+    [Storable]
+    DistanceMeasure distMeasure;
+
+    [Storable]
+    bool diversionAllowed;
+
+    public MoveVehicleAction(
+      Guid vehicleId, 
+      double targetX, double targetY, VehicleAction action, Order order, bool diversionAllowed, DistanceMeasure distMeasure)
+      : base(vehicleId) {
+        this.targetX = targetX;
+        this.targetY = targetY;
+        this.action = action;
+        this.order = order;
+        this.serviceTime = 0;
+        this.completed = false;
+        this.diversionAllowed = diversionAllowed;
+        this.interruptable = diversionAllowed;
+        this.distMeasure = distMeasure;
+
+        this.sourceX = -1;
+        this.sourceY = -1;
+    }
+    [StorableConstructor]
+    protected MoveVehicleAction(bool deserializing) : base(deserializing) {
+    }
+    protected MoveVehicleAction(MoveVehicleAction original, Cloner cloner)
+      : base(original, cloner) {
+      this.targetX = original.targetX;
+      this.sourceX = original.sourceX;
+      this.targetY = original.targetY;
+      this.sourceY = original.sourceY;
+      this.action = original.action;
+      this.order = cloner.Clone<Order>(original.order);
+      this.serviceTime = original.serviceTime;
+      this.completed = original.completed;
+      this.interruptable = original.interruptable;
+      this.distMeasure = cloner.Clone<DistanceMeasure>(original.distMeasure);
+      this.diversionAllowed = original.diversionAllowed;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MoveVehicleAction(this, cloner);
+    }
+
+    protected override bool ActionInterruptable() {
+      return interruptable;
+    }
+
+    public override bool ActionCompleted() {
+      return completed;
+    }
+
+    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
+      Vehicle vehicle = baseObject as Vehicle;
+      lock (vehicle) {
+        if ((action == VehicleAction.Pickup && (order.OrderState != OrderState.Waiting && order.OrderState != OrderState.PickingUp)) ||
+           (action == VehicleAction.Deliver && ((order.OrderState != OrderState.PickedUp && order.OrderState != OrderState.Delivering)
+              || !vehicle.PickedUpOrders.Contains(order.Id))) ||
+           (order != null && (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id))) {
+          if (vehicle.VehicleState != VehicleState.InvalidAction) {
+            vehicle.InvalidActions++;
+
+            vehicle.VehicleState = VehicleState.InvalidAction;
+            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+          }
+
+          if (diversionAllowed)
+            vehicle.ReadyTime = simulationTime;
+          interruptable = diversionAllowed;
+          completed = diversionAllowed;
+
+          if (diversionAllowed)
+            return simulationTime;
+          else {
+            if (order != null) {
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderFailed, BaseObject = order });
+              order = null;
+              action = VehicleAction.Invalid;
+            }
+          }
+        }
+
+        if (sourceX == -1) {
+          sourceX = vehicle.PositionX;
+          sourceY = vehicle.PositionY;
+        }
+
+        vehicle.TargetPositionX = targetX;
+        vehicle.TargetPositionY = targetY;
+        vehicle.CurrentAction = action;
+        if (order == null)
+          vehicle.CurrentOrder = Guid.Empty;
+        else {
+          if (!diversionAllowed)
+            order.Vehicle = vehicle.Id;
+          vehicle.CurrentOrder = order.Id;
+          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+        }
+
+        if (action == VehicleAction.Wait || action == VehicleAction.Park)
+          if (diversionAllowed)
+            vehicle.ReadyTime = simulationTime;
+
+        double tx, ty, length;
+        distMeasure.Move(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY, tickTime, vehicle.MoveInfo,
+          out tx, out ty, out length);
+
+        if (!diversionAllowed) {
+          double time = simulationTime;
+          time += distMeasure.GetDistance(sourceX, sourceY, vehicle.PositionX, vehicle.PositionY, targetX, targetY);
+          if (action == VehicleAction.Pickup) {
+            if (time < order.PickupReadyTime)
+              time = order.PickupReadyTime;
+
+            time += order.PickupServiceTime - serviceTime;
+          } else if (action == VehicleAction.Deliver) {
+            if (time < order.DeliveryReadyTime)
+              time = order.DeliveryReadyTime;
+
+            time += order.DeliveryServiceTime - serviceTime;
+          }
+
+          vehicle.ReadyTime = time;
+        }
+
+        vehicle.PositionX = tx;
+        vehicle.PositionY = ty;
+
+        if (length > 0) {
+          vehicle.Distance += length;
+          tickTime -= length;
+          simulationTime += length;
+
+          if (vehicle.VehicleState != VehicleState.Moving) {
+            vehicle.VehicleState = VehicleState.Moving;
+            changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+          }
+          changes.Add(
+            new PDChange() { ChangeType = SimulationStateChange.VehicleMoved, BaseObject = baseObject });
+        }
+
+        if (vehicle.PositionX == targetX && vehicle.PositionY == targetY) {
+          if (action == VehicleAction.Pickup) {
+            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
+              throw new Exception("Order already assigned");
+
+            if (simulationTime < order.PickupReadyTime) {
+              if (vehicle.VehicleState != VehicleState.Waiting) {
+                if (diversionAllowed)
+                  vehicle.ReadyTime = simulationTime;
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                interruptable = diversionAllowed;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              double waitTime = Math.Min(tickTime,
+                order.PickupReadyTime - simulationTime);
+
+              simulationTime += waitTime;
+              tickTime -= waitTime;
+            }
+
+            //pickup
+            if (simulationTime >= order.PickupReadyTime &&
+              tickTime > 0) {
+              if (vehicle.VehicleState != VehicleState.Servicing) {
+                if (diversionAllowed) {
+                  vehicle.ReadyTime = simulationTime;
+                  vehicle.ReadyTime += order.PickupServiceTime;
+                }
+
+                vehicle.VehicleState = VehicleState.Servicing;
+                interruptable = false;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              if (order.OrderState != OrderState.PickingUp) {
+                order.Vehicle = vehicle.Id;
+                order.OrderState = OrderState.PickingUp;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+              }
+
+              if (serviceTime == 0 && simulationTime > order.PickupDueTime) {
+                order.Tardiness += simulationTime - order.PickupDueTime;
+              }
+
+              double service = Math.Min(tickTime,
+                order.PickupServiceTime - serviceTime);
+
+              serviceTime += service;
+              simulationTime += service;
+              tickTime -= service;
+
+              //load
+              if (serviceTime == order.PickupServiceTime) {
+                vehicle.Capacity -= order.Demand;
+
+                if (vehicle.Capacity < 0) {
+                  vehicle.Overload = -vehicle.Capacity;
+                  vehicle.Capacity = 0;
+                }
+
+                vehicle.PickedUpOrders.Add(order.Id);
+                order.Vehicle = vehicle.Id;
+                order.OrderState = OrderState.PickedUp;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+                completed = true;
+              }
+            }
+          } else if (action == VehicleAction.Deliver) {
+            if (order.Vehicle != Guid.Empty && order.Vehicle != vehicle.Id)
+              throw new Exception("Order already assigned");
+
+            if (simulationTime < order.DeliveryReadyTime) {
+              if (vehicle.VehicleState != VehicleState.Waiting) {
+                if (diversionAllowed)
+                  vehicle.ReadyTime = simulationTime;
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                interruptable = diversionAllowed;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              double waitTime = Math.Min(tickTime,
+                order.DeliveryReadyTime - simulationTime);
+
+              simulationTime += waitTime;
+              tickTime -= waitTime;
+            }
+
+            //deliver
+            if (simulationTime >= order.DeliveryReadyTime &&
+              tickTime > 0) {
+              if (vehicle.VehicleState != VehicleState.Servicing) {
+                if (diversionAllowed) {
+                  vehicle.ReadyTime = simulationTime;
+                  vehicle.ReadyTime += order.DeliveryServiceTime;
+                }
+
+                vehicle.VehicleState = VehicleState.Servicing;
+                interruptable = false;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+              }
+
+              if (order.OrderState != OrderState.Delivering) {
+                order.OrderState = OrderState.Delivering;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+              }
+
+              if (serviceTime == 0 && simulationTime > order.DeliveryDueTime) {
+                order.Tardiness += simulationTime - order.DeliveryDueTime;
+              }
+
+              double service = Math.Min(tickTime,
+                order.DeliveryServiceTime - serviceTime);
+
+              serviceTime += service;
+              simulationTime += service;
+              tickTime -= service;
+
+              //load
+              if (serviceTime == order.DeliveryServiceTime) {
+                vehicle.Capacity += order.Demand;
+                vehicle.PickedUpOrders.Remove(order.Id);
+                order.OrderState = OrderState.Delivered;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.OrderState, BaseObject = order });
+
+                vehicle.VehicleState = VehicleState.Waiting;
+                changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+                completed = true;
+              }
+            }
+          } else if (action == VehicleAction.Park) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.Parked) {
+              vehicle.VehicleState = VehicleState.Parked;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+
+              if (vehicle.PositionX == vehicle.DepotX && vehicle.PositionY == vehicle.DepotY) {
+                if (simulationTime > vehicle.DueTime) {
+                  vehicle.Tardiness = simulationTime - vehicle.DueTime;
+                }
+              }
+            }
+          } else if (action == VehicleAction.Wait) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.Waiting) {
+              vehicle.VehicleState = VehicleState.Waiting;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+            }
+          } else if (action == VehicleAction.Invalid) {
+            completed = true;
+
+            if (vehicle.VehicleState != VehicleState.InvalidAction) {
+              vehicle.VehicleState = VehicleState.InvalidAction;
+              changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+            }
+          }
+        }
+
+        return simulationTime;
+      }
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDAction.cs	(revision 16099)
@@ -0,0 +1,128 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+
+namespace HeuristicLab.PDPSimulation {
+  [StorableClass]
+  public abstract class PDAction: Item {
+    [Storable]
+    private Guid baseObjectId;
+
+    public Guid BaseObjectId {
+      get { return baseObjectId; }
+    }
+
+    [Storable]
+    protected PDAction successor;
+
+    public PDAction Successor {
+      get { return successor; }
+    }
+
+    public void AppendAction(PDAction action, bool recursive) {
+      if (!action.BaseObjectId.Equals(this.BaseObjectId))
+        throw new Exception("Can only append actions of the same object");
+      
+      PDAction predecessor = this;
+      while (predecessor.successor != null && 
+            (recursive || predecessor.ActionCompleted()))
+        predecessor = predecessor.successor;
+
+      predecessor.successor = action;
+    }
+
+    public bool IsCompleted {
+      get {
+        return ActionCompleted() &&
+          (successor == null || successor.IsCompleted);
+      }
+    }
+
+    protected abstract bool ActionInterruptable();
+
+    public bool Interruptable() {
+      PDAction action = this;
+
+      while (action != null && action.ActionCompleted())
+        action = action.successor;
+
+      return action == null || action.ActionInterruptable();
+    }
+
+    public abstract bool ActionCompleted();
+
+    protected abstract double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes);
+
+    public List<PDChange> Perform(BaseObject baseObject, double simulationTime, double timeStep) {
+      List<PDChange> changes = new List<PDChange>();
+
+      lock (this) {
+        double startTime = simulationTime;
+
+        double tickTime = timeStep;
+        bool complete = ActionCompleted();
+        if (!complete && tickTime > 0) {
+          simulationTime = Perform(baseObject, simulationTime, tickTime, changes);
+          complete = ActionCompleted();
+        }
+
+        PDAction next = successor;
+        while (complete && next != null) {
+          tickTime = timeStep - (simulationTime - startTime);
+
+          complete = next.ActionCompleted();
+          if (!complete && tickTime > 0) {
+            simulationTime = next.Perform(baseObject, simulationTime, tickTime, changes);
+            complete = next.ActionCompleted();
+          }
+
+          next = next.successor;
+        }
+      }
+
+      return changes;
+    }
+
+    public virtual bool Obsoletes(PDAction action) {
+      return this.BaseObjectId.Equals(action.BaseObjectId);
+    }
+
+    protected PDAction(Guid baseObjectId) {
+      this.baseObjectId = baseObjectId;
+    }
+
+    [StorableConstructor]
+    protected PDAction(bool deserializing) : base(deserializing) { }
+    protected PDAction(PDAction original, Cloner cloner)
+      : base(original, cloner) {
+        baseObjectId = original.baseObjectId;
+        successor = cloner.Clone<PDAction>(original.successor);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDChange.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDChange.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/PDChange.cs	(revision 16099)
@@ -0,0 +1,35 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.PDPSimulation {
+  public enum SimulationStateChange { OrderCreated, OrderState, OrderFailed, VehicleCreated, VehicleMoved, VehicleState, NoMoreOrders }
+  
+  [StorableClass]
+  public class PDChange : Item {
+    [Storable]
+    public BaseObject BaseObject { get; set; }
+
+    [Storable]
+    public SimulationStateChange ChangeType { get; set; }
+
+    public PDChange() {
+    }
+
+    [StorableConstructor]
+    protected PDChange(bool deserializing) : base(deserializing) { }
+    protected PDChange(PDChange original, Cloner cloner)
+      : base(original, cloner) {
+        BaseObject = cloner.Clone<BaseObject>(original.BaseObject);
+        ChangeType = original.ChangeType;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PDChange(this, cloner);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/WaitAction.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/WaitAction.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/SimulationModel/WaitAction.cs	(revision 16099)
@@ -0,0 +1,57 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.DomainModel;
+using HeuristicLab.PDPSimulation.DistanceMeasures;
+
+namespace HeuristicLab.PDPSimulation {  
+  [StorableClass]
+  public class WaitAction: PDAction {    
+    [Storable]
+    double waitingTime;
+
+    public WaitAction(Guid vehicleId, double waitingTime)
+      : base(vehicleId) {
+        this.waitingTime = waitingTime;
+    }
+    [StorableConstructor]
+    protected WaitAction(bool deserializing) : base(deserializing) {
+    }
+    protected WaitAction(WaitAction original, Cloner cloner)
+      : base(original, cloner) {
+        this.waitingTime = original.waitingTime;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WaitAction(this, cloner);
+    }
+
+    protected override bool ActionInterruptable() {
+      return true;
+    }
+
+    public override bool ActionCompleted() {
+      return waitingTime <= double.Epsilon;
+    }
+
+    protected override double Perform(BaseObject baseObject, double simulationTime, double tickTime, List<PDChange> changes) {
+      double time = Math.Min(tickTime, waitingTime);
+      waitingTime -= time;
+
+      simulationTime += time;
+
+      Vehicle vehicle = baseObject as Vehicle;
+      lock (vehicle) {
+        if ((time > 0) && (vehicle.VehicleState != VehicleState.Waiting)) {
+          vehicle.ReadyTime = 0;
+          vehicle.VehicleState = VehicleState.Waiting;
+          changes.Add(new PDChange() { ChangeType = SimulationStateChange.VehicleState, BaseObject = baseObject });
+        }
+      }
+
+      return simulationTime;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitFirstWaitingStrategy.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitFirstWaitingStrategy.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitFirstWaitingStrategy.cs	(revision 16099)
@@ -0,0 +1,97 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("WaitFirstWaitingStrategy", "A pickup and delivery waiting strategy.")]
+  [StorableClass]
+  public class WaitFirstWaitingStrategy : WaitingStrategy {
+    protected ValueParameter<BoolValue> OnlyFirstStopParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["OnlyFirstStop"]; }
+    }
+
+    public WaitFirstWaitingStrategy()
+      : base() {
+        Parameters.Add(new ValueParameter<BoolValue>("OnlyFirstStop", "Indicates, if waiting should only occur at the first stop.", new BoolValue(false)));
+    }
+    [StorableConstructor]
+    protected WaitFirstWaitingStrategy(bool deserializing) : base(deserializing) { }
+    protected WaitFirstWaitingStrategy(WaitFirstWaitingStrategy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WaitFirstWaitingStrategy(this, cloner);
+    }
+
+    public static double GetSlack(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) {
+      double slack = 0;
+      double minBuffer = double.MaxValue;
+      int count = tour.Stops.Count;
+      if (!(instance as DynPDPProblemInstance).RelocateBackToDepot)
+        count -= 1;
+      for (int i = stop; i <= count; i++) {
+        int customer = 0;
+        if (i < tour.Stops.Count)
+          customer = tour.Stops[i];
+        int prev = 0;
+        if (i > 0)
+          prev = tour.Stops[i - 1];
+
+        int depots = instance.Depots.Value;
+        double distance = instance.GetDistance(prev, customer, solution);
+        time += distance;
+
+        double arrivalTime = time;
+        double deadline = 0;
+        if (customer > 0) {
+          double readyTime = instance.ReadyTime[customer + depots - 1];
+          if (time < readyTime) {
+            slack += readyTime - time;
+            time = readyTime;
+            arrivalTime = time;
+          }
+
+          double serviceTime = instance.ServiceTime[customer - 1];
+          time += serviceTime;
+
+          deadline = instance.DueTime[customer + depots - 1];
+        } else {
+          int depot = instance.GetDepot(prev, solution);
+          deadline = instance.DueTime[depot];
+        }
+
+        double buffer = Math.Max(0, Math.Max(slack, deadline - arrivalTime + slack));
+        if (buffer < minBuffer)
+          minBuffer = buffer;
+      }
+
+      return Math.Floor(minBuffer * 100) / 100;
+    }
+
+    public override double GetWaitingTime(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) {
+      bool onlyFirstStop = OnlyFirstStopParameter.Value.Value;
+      
+      int vehicle = solution.GetVehicleAssignment(solution.GetTourIndex(tour));
+      bool moving = instance.VehicleStates[vehicle] == DomainModel.VehicleState.Moving;
+
+      if (onlyFirstStop) {
+        if ((!moving && stop != 0) || (moving && stop != 1))
+          return 0;
+      } else {
+        if (moving && stop == 0)
+          return 0;
+      }
+
+      return GetSlack(time, instance, solution, tour, stop);
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitingStrategy.cs
===================================================================
--- /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitingStrategy.cs	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/WaitingStrategies/WaitingStrategy.cs	(revision 16099)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
+using HeuristicLab.PDPSimulation.Operators;
+using HeuristicLab.Problems.VehicleRouting;
+using HeuristicLab.Problems.VehicleRouting.Interfaces;
+
+namespace HeuristicLab.PDPSimulation {
+  [Item("Waiting strategy", "A pickup and delivery waiting strategy.")]
+  [StorableClass]
+  public abstract class WaitingStrategy : ParameterizedNamedItem {
+    [Storable]
+    protected PickupDeliveryScenario scenario;
+    
+    public WaitingStrategy()
+      : base() {
+    }
+    [StorableConstructor]
+    protected WaitingStrategy(bool deserializing) : base(deserializing) { }
+    protected WaitingStrategy(WaitingStrategy original, Cloner cloner)
+      : base(original, cloner) {
+        this.scenario = cloner.Clone<PickupDeliveryScenario>(original.scenario);
+    }
+
+    public virtual void SetScenario(PickupDeliveryScenario scenario) {
+      if (scenario != null) {
+        this.scenario = scenario;
+      }
+    }
+
+    public abstract double GetWaitingTime(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop);
+
+    public virtual double GetBufferTime(double time, DynPDPProblemInstance instance, IVRPEncoding solution, Tour tour, int stop) {
+      return 0;
+    }
+  }
+}
Index: /branches/1955_DynamicVehicleRouting/PDPSimulation.sln
===================================================================
--- /branches/1955_DynamicVehicleRouting/PDPSimulation.sln	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/PDPSimulation.sln	(revision 16099)
@@ -0,0 +1,52 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{89C26307-57A6-4A44-BB5F-27B39D093EE5}"
+	ProjectSection(SolutionItems) = preProject
+		Build.cmd = Build.cmd
+		PreBuildEvent.cmd = PreBuildEvent.cmd
+	EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.PDPSimulation-3.3", "HeuristicLab.PDPSimulation\3.3\HeuristicLab.PDPSimulation-3.3.csproj", "{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.PDPSimulation.Views-3.3", "HeuristicLab.PDPSimulation.Views\3.3\HeuristicLab.PDPSimulation.Views-3.3.csproj", "{08FBD39B-C785-4199-BA39-A7AB87E364C6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|x64.ActiveCfg = Debug|x64
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|x64.Build.0 = Debug|x64
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|x86.ActiveCfg = Debug|x86
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Debug|x86.Build.0 = Debug|x86
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|x64.ActiveCfg = Release|x64
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|x64.Build.0 = Release|x64
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|x86.ActiveCfg = Release|x86
+		{F8815280-FA2D-4B3B-B3FD-242863ADB4FF}.Release|x86.Build.0 = Release|x86
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|x64.ActiveCfg = Debug|x64
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|x64.Build.0 = Debug|x64
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|x86.ActiveCfg = Debug|x86
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Debug|x86.Build.0 = Debug|x86
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|x64.ActiveCfg = Release|x64
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|x64.Build.0 = Release|x64
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|x86.ActiveCfg = Release|x86
+		{08FBD39B-C785-4199-BA39-A7AB87E364C6}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/1955_DynamicVehicleRouting/PreBuildEvent.cmd
===================================================================
--- /branches/1955_DynamicVehicleRouting/PreBuildEvent.cmd	(revision 16099)
+++ /branches/1955_DynamicVehicleRouting/PreBuildEvent.cmd	(revision 16099)
@@ -0,0 +1,2 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
