Index: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj
===================================================================
--- branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj	(revision 8812)
+++ branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/HeuristicLab.PDPSimulation-3.3.csproj	(revision 8813)
@@ -136,5 +136,5 @@
     </Reference>
     <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
-    <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -207,4 +207,7 @@
     <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" />
Index: branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs
===================================================================
--- branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs	(revision 8813)
+++ branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/Dispatching.cs	(revision 8813)
@@ -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/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs
===================================================================
--- branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs	(revision 8813)
+++ branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/EarliestDueTimeDispatching.cs	(revision 8813)
@@ -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/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs
===================================================================
--- branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs	(revision 8813)
+++ branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/NearestDestinationDispatching.cs	(revision 8813)
@@ -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/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs
===================================================================
--- branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs	(revision 8812)
+++ branches/DynamicVehicleRouting/HeuristicLab.PDPSimulation/3.3/Optimizers/LocalUpdate/PriorityDispatching.cs	(revision 8813)
@@ -14,18 +14,5 @@
   [Item("PriorityDispatching", "")]
   [StorableClass]
-  public abstract class PriorityDispatching : 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)));
-    }
-
-
+  public abstract class PriorityDispatching : Dispatching {
     [StorableConstructor]
     protected PriorityDispatching(bool deserializing) : base(deserializing) { }
@@ -34,74 +21,7 @@
     }
 
-    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 double CalculatePriority(IDictionary<string, double> variables);
 
-    private void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
+    protected override void GetHighestPriorityOrder(DynPDPProblemInstance instance, Vehicle vehicle, IEnumerable<Order> orders, out Order order, out double priority) {
       Order best = null;
       double bestPriority = double.MinValue;
@@ -167,29 +87,4 @@
       priority = bestPriority;
     }
-
-    private bool IsPickup(Order o, DynPDPProblemInstance instance) {
-      return instance.Demand[Instance.GetStops(o.Id).First()] > 0;
-    }
-
-    private 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;
-      }
-    }
-
-    private 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();
-      }
-    }
   }
 }
