Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/Container3DView.xaml.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/Container3DView.xaml.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/Container3DView.xaml.cs	(revision 15554)
@@ -74,5 +74,5 @@
     private Dictionary<int, DiffuseMaterial> materials;
 
-    public ObservableDictionary<BinPacking3D.PackingPosition, ResidualSpace> ResidualSpaces { get; set; }
+    public ObservableDictionary<BinPacking3D.PackingPosition, IList<ResidualSpace>> ResidualSpaces { get; set; }
     public ObservableCollection<BinPacking3D.PackingPosition> ExtremePoints { get; set; }
 
@@ -81,5 +81,5 @@
       camMain.Position = new Point3D(0.5, 3, 3); // for design time we use a different camera position 
       materials = new Dictionary<int, DiffuseMaterial>();
-      ResidualSpaces = new ObservableDictionary<BinPacking3D.PackingPosition, ResidualSpace>();
+      ResidualSpaces = new ObservableDictionary<BinPacking3D.PackingPosition, IList<ResidualSpace>>();
       ExtremePoints = new ObservableCollection<BinPacking3D.PackingPosition>();
       selectedExtremePointIndex = -1;
@@ -240,17 +240,19 @@
     private void AddResidualSpacesForExtremePoint(Model3DGroup modelGroup, BinPacking3D.PackingPosition extremePoint) {
       if (showResidualSpaces) {
-        var rs = ResidualSpaces[extremePoint];
-        var containerModel1 = new GeometryModel3D(new MeshGeometry3D(), new DiffuseMaterial(new SolidColorBrush(residualSpaceColor)));
-
-        modelGroup.Children.Add(containerModel1);
-        AddWireframeCube((MeshGeometry3D)containerModel1.Geometry,
-          extremePoint.X,
-          extremePoint.Y,
-          extremePoint.Z,
-          rs.Width,
-          rs.Height,
-          rs.Depth);
-
+        foreach (var rs in ResidualSpaces[extremePoint]) {
+          var containerModel1 = new GeometryModel3D(new MeshGeometry3D(), new DiffuseMaterial(new SolidColorBrush(residualSpaceColor)));
+
+          modelGroup.Children.Add(containerModel1);
+
+          AddWireframeCube((MeshGeometry3D)containerModel1.Geometry,
+            extremePoint.X,
+            extremePoint.Y,
+            extremePoint.Z,
+            rs.Width,
+            rs.Height,
+            rs.Depth);
+        }
       }
+       
     }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/PackingPlan3DView.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/PackingPlan3DView.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking.Views/3.3/PackingPlan3DView.cs	(revision 15554)
@@ -24,4 +24,5 @@
 using HeuristicLab.MainForm;
 using HeuristicLab.Problems.BinPacking3D;
+using System.Collections.Generic;
 
 namespace HeuristicLab.Problems.BinPacking.Views {
@@ -75,9 +76,9 @@
         itemSelection.Items.Add(item.Key);
       }
-      foreach (var ep in ((BinPacking3D.BinPacking3D)packing).ExtremePoints) {
-        var rs = ((BinPacking3D.BinPacking3D)packing).ResidualSpaces[ep];
+      foreach (var extremPoint in ((BinPacking3D.BinPacking3D)packing).ExtremePoints) {
+        var ep = extremPoint.Key;
         extremePointsSelection.Items.Add($"({ep.X}, {ep.Y}, {ep.Z})");
         packingPlan3D.ExtremePoints.Add(ep);
-        packingPlan3D.ResidualSpaces.Add(ep, rs);
+        packingPlan3D.ResidualSpaces.Add(ep, extremPoint.Value as IList<ResidualSpace>);
       }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs	(revision 15554)
@@ -34,19 +34,14 @@
   [StorableClass]
   public class BinPacking3D : BinPacking<PackingPosition, PackingShape, PackingItem> {
-
+    
     [Storable]
-    public Dictionary<PackingPosition, ResidualSpace> ResidualSpaces { get; set; }
-
-    [Storable]
-    public SortedSet<PackingPosition> ExtremePoints { get; protected set; }
+    public IDictionary<PackingPosition, IEnumerable<ResidualSpace>> ExtremePoints { get; protected set; }
 
 
     public BinPacking3D(PackingShape binShape)
       : base(binShape) {
-      ExtremePoints = new SortedSet<PackingPosition>();
-      ResidualSpaces = new Dictionary<PackingPosition, ResidualSpace>();
+      ExtremePoints = new SortedList<PackingPosition, IEnumerable<ResidualSpace>>();
       
-      ExtremePoints.Add(binShape.Origin);
-      ResidualSpaces.Add(binShape.Origin, new ResidualSpace(BinShape.Width, BinShape.Height, BinShape.Depth));
+      ExtremePoints.Add(binShape.Origin, new List<ResidualSpace>() {ResidualSpace.Create(binShape.Width, binShape.Height, binShape.Depth)});
     }
 
@@ -56,9 +51,13 @@
     protected BinPacking3D(BinPacking3D original, Cloner cloner)
       : base(original, cloner) {
-      this.ResidualSpaces = new Dictionary<PackingPosition, ResidualSpace>();
-      foreach (var o in original.ResidualSpaces)
-        this.ResidualSpaces.Add(cloner.Clone(o.Key), ResidualSpace.Create(o.Value));
-
-      this.ExtremePoints = new SortedSet<PackingPosition>(original.ExtremePoints.Select(p => cloner.Clone(p)));
+
+      this.ExtremePoints = new SortedList<PackingPosition, IEnumerable<ResidualSpace>>();
+      foreach (var extremePoint in original.ExtremePoints) {
+        var residualSpaces = new List<ResidualSpace>();
+        foreach (var residualSpace in extremePoint.Value) {
+          residualSpaces.Add(cloner.Clone(residualSpace));
+        }
+        ExtremePoints.Add(cloner.Clone(extremePoint.Key), residualSpaces);
+      }
     }
 
@@ -67,16 +66,5 @@
     }
 
-
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      // BackwardsCompatibility3.3
-      #region Backwards compatible code, remove with 3.4
-      if (ResidualSpaces == null)
-        ResidualSpaces = new Dictionary<PackingPosition, ResidualSpace>();
-      #endregion
-    }
-
-
-
+    
 
     /// <summary>
@@ -90,5 +78,4 @@
       Positions[itemID] = position;
       ExtremePoints.Remove(position);
-      ResidualSpaces.Remove(position);
     }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/ExtremePointCreator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/ExtremePointCreator.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/ExtremePointCreator.cs	(revision 15554)
@@ -46,7 +46,7 @@
         // Projecting onto the XZ-plane
         var below = ProjectDown(binPacking, sourcePoint);
-        var residualSpace = CalculateResidualSpace(binPacking, below);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, below, residualSpace)) {
+        var residualSpaces = CalculateResidualSpace(binPacking, below);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, below, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -56,7 +56,7 @@
         // Projecting onto the XY-plane
         var back = ProjectBackward(binPacking, sourcePoint);
-        residualSpace = CalculateResidualSpace(binPacking, back);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, back, residualSpace)) {
+        residualSpaces = CalculateResidualSpace(binPacking, back);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, back, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -71,7 +71,7 @@
         // Projecting onto the YZ-plane
         var left = ProjectLeft(binPacking, sourcePoint);
-        var residualSpace = CalculateResidualSpace(binPacking, left);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, left, residualSpace)) {
+        var residualSpaces = CalculateResidualSpace(binPacking, left);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, left, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -81,7 +81,7 @@
         // Projecting onto the XY-plane
         var back = ProjectBackward(binPacking, sourcePoint);
-        residualSpace = CalculateResidualSpace(binPacking, back);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, back, residualSpace)) {
+        residualSpaces = CalculateResidualSpace(binPacking, back);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, back, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -96,7 +96,7 @@
         // Projecting onto the XZ-plane
         var below = ProjectDown(binPacking, sourcePoint);
-        var residualSpace = CalculateResidualSpace(binPacking, below);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, below, residualSpace)) {
+        var residualSpaces = CalculateResidualSpace(binPacking, below);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, below, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -106,7 +106,7 @@
         // Projecting onto the YZ-plane
         var left = ProjectLeft(binPacking, sourcePoint);
-        residualSpace = CalculateResidualSpace(binPacking, left);
-        if (!residualSpace.IsZero()
-          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, left, residualSpace)) {
+        residualSpaces = CalculateResidualSpace(binPacking, left);
+        if (residualSpaces.Count() > 0
+          && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, left, residualSpaces)) {
           // add only if the projected point's residual space is not a sub-space
           // of another extreme point's residual space
@@ -191,7 +191,36 @@
     /// <param name="residualSpace"></param>
     /// <returns></returns>
-    protected virtual bool IsWithinResidualSpaceOfAnotherExtremePoint(BinPacking3D binPacking, Vector3D pos, ResidualSpace residualSpace) {
-      var eps = binPacking.ExtremePoints.Where(x => !pos.Equals(x) && pos.IsInside(x, binPacking.ResidualSpaces[x]));
-      return eps.Any(x => IsWithinResidualSpaceOfAnotherExtremePoint(pos, residualSpace, x, binPacking.ResidualSpaces[x]));
+    protected bool IsWithinResidualSpaceOfAnotherExtremePoint(BinPacking3D binPacking, Vector3D pos, ResidualSpace residualSpace) {
+      var eps = binPacking.ExtremePoints.Where(x => !pos.Equals(x.Key) && pos.IsInside(x.Key, x.Value));
+      return eps.Any(x => IsWithinResidualSpaceOfAnotherExtremePoint(pos, residualSpace, x.Key, x.Value));
+    }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="pos"></param>
+    /// <param name="residualSpaces"></param>
+    /// <returns></returns>
+    protected bool IsWithinResidualSpaceOfAnotherExtremePoint(BinPacking3D binPacking, Vector3D pos, IEnumerable<ResidualSpace> residualSpaces) {
+      foreach (var residualSpace in residualSpaces) {
+        if (IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, pos, residualSpace)) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+
+    /// <summary>
+    /// Returns true, if the given poisition and the related residual space is within the residual space of the given extreme point
+    /// </summary>
+    /// <param name="pos"></param>
+    /// <param name="rsPos"></param>
+    /// <param name="ep"></param>
+    /// <param name="rsEp"></param>
+    /// <returns></returns>
+    protected bool IsWithinResidualSpaceOfAnotherExtremePoint(Vector3D pos, ResidualSpace rsPos, PackingPosition ep, IEnumerable<ResidualSpace> rsEp) {
+      return rsEp.Any(x => IsWithinResidualSpaceOfAnotherExtremePoint(pos, rsPos, ep, x));
     }
 
@@ -211,51 +240,12 @@
 
     /// <summary>
-    /// Calculates the residual space for a given bin packing and position.
-    /// It returns the residual space as a tuple which contains the dimensions
-    /// </summary>
-    /// <param name="binPacking"></param>
-    /// <param name="pos"></param>
-    /// <returns>A Tuple(width, Height, Depth)</width></returns>
-    protected virtual ResidualSpace CalculateResidualSpace(BinPacking3D binPacking, Vector3D pos) {
-      //return ResidualSpaceCalculator.Create().CalculateResidualSpace(binPacking, pos).First();
-      return new ResidualSpace(CalculateResidualSpaceOld(binPacking, pos));
-    }
-
-    protected virtual Tuple<int, int, int> CalculateResidualSpaceOld(BinPacking3D binPacking, Vector3D pos) {
-
-      if (pos == null) {
-        return Tuple.Create(0, 0, 0);
-      }
-      var itemPos = binPacking.Items.Select(x => new {
-        Item = x.Value,
-        Position = binPacking.Positions[x.Key]
-      });
-      Vector3D limit = new Vector3D() {
-        X = binPacking.BinShape.Width,
-        Y = binPacking.BinShape.Height,
-        Z = binPacking.BinShape.Depth
-      };
-
-      if (pos.X < limit.X && pos.Y < limit.Y && pos.Z < limit.Z) {
-        var rightLimit = ProjectRight(binPacking, pos);
-        var upLimit = ProjectUp(binPacking, pos);
-        var forwardLimit = ProjectForward(binPacking, pos);
-        if (rightLimit.X > 0) {
-          limit.X = rightLimit.X;
-        }
-        if (upLimit.Y > 0) {
-          limit.Y = upLimit.Y;
-        }
-        if (forwardLimit.Z > 0) {
-          limit.Z = forwardLimit.Z;
-        }
-      }
-
-      if (limit.X - pos.X <= 0 || limit.Y - pos.Y <= 0 || limit.Z - pos.Z <= 0) {
-        return Tuple.Create(0, 0, 0);
-      }
-      return Tuple.Create(limit.X - pos.X, limit.Y - pos.Y, limit.Z - pos.Z);
-    }
-
+    /// Calculates the residual spaces for a given bin packing and position.
+    /// It returns a collection of residual spaces
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="pos"></param>
+    /// <returns></returns>
+    protected abstract IEnumerable<ResidualSpace> CalculateResidualSpace(BinPacking3D binPacking, Vector3D pos);
+    
     #endregion
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/LineProjectionBasedEPCreator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/LineProjectionBasedEPCreator.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/LineProjectionBasedEPCreator.cs	(revision 15554)
@@ -15,15 +15,6 @@
   public class LineProjectionBasedEPCreator : ExtremePointCreator {
 
-
-
-
     protected override void UpdateExtremePoints(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      // After a item has been placed, the residual space has to be recalculated.
-      //RecalculateResidualSpaces(binPacking);
-
-      //GenerateNewExtremePointsForItem(binPacking, item, position);
-
       binPacking.ExtremePoints.Clear();
-      binPacking.ResidualSpaces.Clear();
 
       foreach (var i in binPacking.Items) {
@@ -32,15 +23,15 @@
         GenerateNewExtremePointsForItem(binPacking, it, p);
       }
-      //RecalculateResidualSpaces(binPacking);
-    }
-
-    /// <summary>
-    /// Adds an new extreme point an the related residual space to a given bin packing.
-    /// - The given position has to be valid
-    /// - The residual space must not be zero
-    /// </summary>
-    /// <param name="binPacking"></param>
-    /// <param name="position"></param>
-    /// <returns></returns>
+    }
+
+    /// <summary>
+    /// Adds a new extreme point an the related residual spaces to a given bin packing.
+    /// - The given position has to be valid.
+    /// - The extreme point does not exist in the bin packing.
+    /// - There must be at minimum one valid residual space. A residual space is invalid if the space is zero.
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="position"></param>
+    /// <returns>True = the given point and its related residual spaces were successfully added to the bin packing</returns>
     protected override bool AddExtremePoint(BinPacking3D binPacking, PackingPosition position) {
       if (position == null) {
@@ -48,20 +39,50 @@
       }
 
-      if (PointIsInItem(binPacking, new Vector3D(position))) {
+      if (PointIsInAnyItem(binPacking, new Vector3D(position))) {
         return false;
       }
 
+      if (binPacking.ExtremePoints.ContainsKey(position)) {
+        return false;
+      }
+
       var rs = CalculateResidualSpace(binPacking, new Vector3D(position));
 
-      if (rs.IsZero()) {
+      if (rs.Count() <= 0) {
         return false;
       }
 
-      if (!binPacking.ExtremePoints.Add(position)) {
+      // todo 
+      /*
+       ist der extrempunkt im residual space eines anderen muss ueberprueft werden:
+          - ist der andere ep in der luft, kann auch dieser hinzugefuegt werden.
+          - hat der andere ep ein item unterhalb, darf dieser nicht hinzugefuegt werden.
+       -> neu methode basierend auf IsWithinResidualSpaceOfAnotherExtremePoint, die den ep oder rs zurueck gibt, der einen anderen rs einschließt.
+          eventuell gehoert diese logik in den ResidualSpaceCreator.
+      if (LiesOnAnyItem(binPacking, position)) {
         return false;
-      }
-
-      binPacking.ResidualSpaces.Add(position, rs);
+      }*/
+
+      binPacking.ExtremePoints.Add(position, rs);
       return true;
+    }
+
+    private bool LiesOnAnyItem(BinPacking3D binPacking, PackingPosition position) {
+      if (position.Y == 0) {
+        return true;
+      }
+
+      var items = binPacking.Items.Where(x => {
+        var itemPosition = binPacking.Positions[x.Key];
+        var item = x.Value;
+        int width = itemPosition.Rotated ? item.Depth : item.Width;
+        int depth = itemPosition.Rotated ? item.Width : item.Depth;
+
+        return itemPosition.Y + item.Height == position.Y &&
+               itemPosition.X <= position.X && position.X < itemPosition.X + width &&
+               itemPosition.Z <= position.Z && position.Z < itemPosition.Z + depth;
+      });
+
+      return items.Count() > 0;
     }
 
@@ -83,5 +104,5 @@
     /// <summary>
     /// This method creates extreme points by using a point projection based method.
-    /// For each item there will be three points created and each of the point will be projected twice.
+    /// For each item there will be created three points and each of the points will be projected twice.
     /// The direction of the projection depends on position of the point.
     /// </summary>
@@ -118,5 +139,7 @@
       if (sourcePoint.X < binPacking.BinShape.Width && sourcePoint.Y < binPacking.BinShape.Height && sourcePoint.Z < binPacking.BinShape.Depth) {
         Vector3D point = projectionMethod?.Invoke(binPacking, sourcePoint);
-        AddExtremePoint(binPacking, new PackingPosition(position.AssignedBin, point.X, point.Y, point.Z));
+        if (point != null) {
+          AddExtremePoint(binPacking, new PackingPosition(position.AssignedBin, point.X, point.Y, point.Z));
+        }
       }
     }
@@ -141,23 +164,36 @@
 
       foreach (var ep in GetEpsOnLeft(binPacking, newItem, position)) {
-        AddExtremePoint(binPacking, ep);
+        AddExtremePoint(binPacking, ep.Key);
       }
 
       foreach (var ep in GetEpsBelow(binPacking, newItem, position)) {
-        AddExtremePoint(binPacking, ep);
+        AddExtremePoint(binPacking, ep.Key);
       }
 
       foreach (var ep in GetEpsBehind(binPacking, newItem, position)) {
-        AddExtremePoint(binPacking, ep);
+        AddExtremePoint(binPacking, ep.Key);
       }
     }
     #endregion
 
-
+    /// <summary>
+    /// Updates the residual spaces.
+    /// It removes not needed ones.
+    /// A residual space will be removed if the space is a subspace of another one and 
+    /// the current one has no item below or both have an item below. 
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="item"></param>
+    /// <param name="position"></param>
     protected override void UpdateResidualSpace(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      return;
-    }
-
-    private bool PointIsInItem(BinPacking3D binPacking, Vector3D point) {
+    }
+
+    /// <summary>
+    /// Returns true if any item in the bin packing encapsulates the given point
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="point"></param>
+    /// <returns></returns>
+    private bool PointIsInAnyItem(BinPacking3D binPacking, Vector3D point) {
       foreach (var item in binPacking.Items) {
         PackingPosition position = binPacking.Positions[item.Key];
@@ -184,23 +220,4 @@
     }
 
-    /// <summary>
-    /// Recalculates the residual spaces if needed.
-    /// It checks if an item is in an residual space and if so the residual space will be recalculated.
-    /// If the residual space has gone to zero, this residual space and its related extreme point will be removed.
-    /// </summary>
-    /// <param name="binPacking"></param>
-    private void RecalculateResidualSpaces(BinPacking3D binPacking) {
-      var recalculatedSpaces = new Dictionary<PackingPosition, ResidualSpace>();
-      foreach (var ep in binPacking.ExtremePoints.ToList()) {
-        var newRs = CalculateResidualSpace(binPacking, new Vector3D(ep));
-        if (!newRs.IsZero() && !PointIsInItem(binPacking, new Vector3D(ep))) {
-          recalculatedSpaces.Add(ep, newRs);
-        } else {
-          binPacking.ExtremePoints.Remove(ep);
-        }
-      }
-      binPacking.ResidualSpaces = recalculatedSpaces;
-    }
-
     protected IEnumerable<Tuple<PackingPosition, PackingItem>> GetItemsBelow(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
       return binPacking.Items.Select(x => new {
@@ -228,31 +245,44 @@
 
     /// <summary>
-    /// Returns the extremepoints on the left side of an given item
-    /// </summary>
-    /// <param name="item"></param>
-    /// <param name="position"></param>
-    /// <returns></returns>
-    private IList<PackingPosition> GetEpsOnLeft(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      IList<PackingPosition> eps = new List<PackingPosition>();
+    /// Returns the extreme points and its related residual spaces on the left side of an given item.
+    /// This extreme points are being created by intersecting two edges on the left side of the given item 
+    /// (left - in front, left - on top) with all edges on the right side of all other items int the bin packing.
+    /// </summary>
+    /// <param name="item"></param>
+    /// <param name="position"></param>
+    /// <returns></returns>
+    private IDictionary<PackingPosition, IEnumerable<ResidualSpace>> GetEpsOnLeft(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
+      var eps = new SortedList<PackingPosition, IEnumerable<ResidualSpace>>();
       IEnumerable<Tuple<PackingPosition, PackingItem>> items = GetItemsOnLeft(binPacking, item, position);
       var edges = GetProjectionEdgesOnLeft(item, position);
 
       foreach (var otherItem in items) {
+        if (position.Equals(otherItem.Item1)) {
+          continue;
+        }
+
         var otherItemEdges = GetEdgesOnRight(otherItem.Item2, otherItem.Item1);
+        // left - in front
         foreach (var ep in IntersectionsForItem(edges[0], otherItemEdges, new Vector3D(1, 0, 0))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
+            // As this edge has a vertical direction, every point of intersection won't have an item below.
+            // So finally it is being projected down.
             var point = ProjectDown(binPacking, ProjectLeft(binPacking, ep));
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
         }
+
+        // left - on top
         foreach (var ep in IntersectionsForItem(edges[1], otherItemEdges, new Vector3D(1, 0, 0))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
             var point = ProjectLeft(binPacking, ep);
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
@@ -264,31 +294,42 @@
 
     /// <summary>
-    /// Returns the extremepoints below of an given item
-    /// </summary>
-    /// <param name="item"></param>
-    /// <param name="position"></param>
-    /// <returns></returns>
-    private IList<PackingPosition> GetEpsBelow(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      IList<PackingPosition> eps = new List<PackingPosition>();
+    /// Returns the extreme points and its related residual spaces below of an given item.
+    /// This extreme points are being created by intersecting two edges below of the given item 
+    /// (below - in front, below - right) with all edges on top side of all other items int the bin packing.
+    /// </summary>
+    /// <param name="item"></param>
+    /// <param name="position"></param>
+    /// <returns></returns>
+    private IDictionary<PackingPosition, IEnumerable<ResidualSpace>> GetEpsBelow(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
+      var eps = new SortedList<PackingPosition, IEnumerable<ResidualSpace>>();
       IEnumerable<Tuple<PackingPosition, PackingItem>> items = GetItemsBelow(binPacking, position);
       var edges = GetProjectionEdgesBelow(item, position);
 
       foreach (var otherItem in items) {
+        if (position.Equals(otherItem.Item1)) {
+          continue;
+        }
+
         var otherItemEdges = GetEdgesOnTop(otherItem.Item2, otherItem.Item1);
+        // below - in front
         foreach (var ep in IntersectionsForItem(edges[0], otherItemEdges, new Vector3D(0, 1, 0))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
             var point = ProjectDown(binPacking, ep);
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
         }
+
+        // below - right
         foreach (var ep in IntersectionsForItem(edges[1], otherItemEdges, new Vector3D(0, 1, 0))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
             var point = ProjectDown(binPacking, ep);
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
@@ -299,31 +340,44 @@
 
     /// <summary>
-    /// Returns 
-    /// </summary>
-    /// <param name="item"></param>
-    /// <param name="position"></param>
-    /// <returns></returns>
-    private IList<PackingPosition> GetEpsBehind(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      IList<PackingPosition> eps = new List<PackingPosition>();
+    /// Returns the extreme points and its related residual spaces below of an given item.
+    /// This extreme points are being created by intersecting two edges below of the given item 
+    /// (right - behind, on top - behind) with all edges on top side of all other items int the bin packing.
+    /// </summary>
+    /// <param name="item"></param>
+    /// <param name="position"></param>
+    /// <returns></returns>
+    private IDictionary<PackingPosition, IEnumerable<ResidualSpace>> GetEpsBehind(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
+      var eps = new SortedList<PackingPosition, IEnumerable<ResidualSpace>>();
       IEnumerable<Tuple<PackingPosition, PackingItem>> items = GetItemsBehind(binPacking, position);
       var edges = GetProjectionEdgesBehind(item, position);
 
       foreach (var otherItem in items) {
+        if (position.Equals(otherItem.Item1)) {
+          continue;
+        }
+
         var otherItemEdges = GetEdgesInFront(otherItem.Item2, otherItem.Item1);
+        // right - behind
         foreach (var ep in IntersectionsForItem(edges[0], otherItemEdges, new Vector3D(0, 0, 1))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
+            // As this edge has a vertical direction, every point of intersection won't have an item below.
+            // So finally it is being projected down.
             var point = ProjectDown(binPacking, ProjectBackward(binPacking, ep));
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
         }
+
+        // on top - behind
         foreach (var ep in IntersectionsForItem(edges[1], otherItemEdges, new Vector3D(0, 0, 1))) {
           if (ep.X < binPacking.BinShape.Width && ep.Y < binPacking.BinShape.Height && ep.Z < binPacking.BinShape.Depth) {
             var point = ProjectBackward(binPacking, ep);
-            var residualSpace = CalculateResidualSpace(binPacking, point);
-            if (!residualSpace.IsZero()) {
-              eps.Add(point.ToPackingPosition(position.AssignedBin));
+            var residualSpaces = CalculateResidualSpace(binPacking, point);
+            var newExtremePoint = point.ToPackingPosition(position.AssignedBin);
+            if (residualSpaces.Count() > 0 && !eps.ContainsKey(newExtremePoint)) {
+              eps.Add(newExtremePoint, residualSpaces);
             }
           }
@@ -452,8 +506,12 @@
 
     /// <summary>
-    /// 
+    /// Returns a collection of points where a given edge (projectedEdge) intersects with other edges.
+    /// The given edge (projectedEdge) will be projected by using the given vector direction
+    /// and a edge of the given edge collection.
+    /// The returned collecten can be empty.
     /// </summary>
     /// <param name="projectedEdge"></param>
     /// <param name="edges"></param>
+    /// <param name="direction"></param>
     /// <returns></returns>
     private IEnumerable<Vector3D> IntersectionsForItem(Edge3D projectedEdge, Edge3D[] edges, Vector3D direction = null) {
@@ -486,10 +544,15 @@
     #endregion
 
-    
-    protected override ResidualSpace CalculateResidualSpace(BinPacking3D binPacking, Vector3D pos) {
-      return ResidualSpaceCalculatorFactory.CreateCalculator().CalculateResidualSpaces(binPacking, pos).First();
+    /// <summary>
+    /// Calculates the residual spaces for an extreme point.
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="pos"></param>
+    /// <returns></returns>
+    protected override IEnumerable<ResidualSpace> CalculateResidualSpace(BinPacking3D binPacking, Vector3D pos) {
+      return ResidualSpaceCalculatorFactory.CreateCalculator().CalculateResidualSpaces(binPacking, pos);
     }
   }
 
-  
+
 }
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/PointProjectionBasedEPCreator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/PointProjectionBasedEPCreator.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ExtremePointCreation/PointProjectionBasedEPCreator.cs	(revision 15554)
@@ -31,41 +31,45 @@
     
     protected override void UpdateResidualSpace(BinPacking3D binPacking, PackingItem item, PackingPosition position) {
-      foreach (var ep in binPacking.ExtremePoints.ToList()) {
-        var rs = binPacking.ResidualSpaces[ep];
-        var depth = position.Rotated ? item.Width : item.Depth;
-        var width = position.Rotated ? item.Depth : item.Width;
-        var changed = false;
-        if (ep.Z >= position.Z && ep.Z < position.Z + depth) {
-          if (ep.X <= position.X && ep.Y >= position.Y && ep.Y < position.Y + item.Height) {
-            var diff = position.X - ep.X;
-            var newRSX = Math.Min(rs.Width, diff);
-            rs = ResidualSpace.Create(newRSX, rs.Height, rs.Depth);
+      foreach (var extremePoint in binPacking.ExtremePoints.ToList()) {
+        var ep = extremePoint.Key;
+        var residualSpaces = extremePoint.Value as IList<ResidualSpace>;
+        for (int i = 0; i < residualSpaces.Count(); i++) {
+          var rs = residualSpaces[i];
+          var depth = position.Rotated ? item.Width : item.Depth;
+          var width = position.Rotated ? item.Depth : item.Width;
+          var changed = false;
+          if (ep.Z >= position.Z && ep.Z < position.Z + depth) {
+            if (ep.X <= position.X && ep.Y >= position.Y && ep.Y < position.Y + item.Height) {
+              var diff = position.X - ep.X;
+              var newRSX = Math.Min(rs.Width, diff);
+              rs = ResidualSpace.Create(newRSX, rs.Height, rs.Depth);
+              changed = true;
+            }
+            if (ep.Y <= position.Y && ep.X >= position.X && ep.X < position.X + width) {
+              var diff = position.Y - ep.Y;
+              var newRSY = Math.Min(rs.Height, diff);
+              rs = ResidualSpace.Create(rs.Width, newRSY, rs.Depth);
+              changed = true;
+            }
+          }
+
+          if (ep.Z <= position.Z &&
+              ep.Y >= position.Y && ep.Y < position.Y + item.Height &&
+              ep.X >= position.X && ep.X < position.X + width) {
+            var diff = position.Z - ep.Z;
+            var newRSZ = Math.Min(rs.Depth, diff);
+            rs = ResidualSpace.Create(rs.Width, rs.Height, newRSZ);
             changed = true;
           }
-          if (ep.Y <= position.Y && ep.X >= position.X && ep.X < position.X + width) {
-            var diff = position.Y - ep.Y;
-            var newRSY = Math.Min(rs.Height, diff);
-            rs = ResidualSpace.Create(rs.Width, newRSY, rs.Depth);
-            changed = true;
+
+          if (changed) {
+            if (!rs.IsZero() && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, new Vector3D(ep), rs)) {
+              residualSpaces[i] = rs;
+            } else {
+              binPacking.ExtremePoints.Remove(ep);
+              break;
+            }
           }
-        }
-
-        if (ep.Z <= position.Z &&
-            ep.Y >= position.Y && ep.Y < position.Y + item.Height &&
-            ep.X >= position.X && ep.X < position.X + width) {
-          var diff = position.Z - ep.Z;
-          var newRSZ = Math.Min(rs.Depth, diff);
-          rs = ResidualSpace.Create(rs.Width, rs.Height, newRSZ);
-          changed = true;
-        }
-
-        if (changed) {
-          if (!rs.IsZero() && !IsWithinResidualSpaceOfAnotherExtremePoint(binPacking, new Vector3D(ep), rs)) {
-            binPacking.ResidualSpaces[ep] = rs;
-          } else {
-            binPacking.ExtremePoints.Remove(ep);
-            binPacking.ResidualSpaces.Remove(ep);
-          }
-        }
+        }        
       }
       return;
@@ -81,18 +85,73 @@
     /// <returns></returns>
     protected override bool AddExtremePoint(BinPacking3D binPacking, PackingPosition position) {
-      if (binPacking.ExtremePoints.Add(position)) {
-        var rs = CalculateResidualSpace(binPacking, new Vector3D(position));
-        binPacking.ResidualSpaces.Add(position, rs);
-        // Check if the existing extreme points are shadowed by the new point
-        // This is, their residual space fit entirely into the residual space of the new point
-        foreach (var ep in binPacking.ExtremePoints.Where(x => x != position && new Vector3D(x).IsInside(position, rs)).ToList()) {
-          if (IsWithinResidualSpaceOfAnotherExtremePoint(new Vector3D(ep), binPacking.ResidualSpaces[ep], position, rs)) {
+      if (binPacking.ExtremePoints.ContainsKey(position)) {
+        return false;
+      }
+
+      var residualSpaces = CalculateResidualSpace(binPacking, new Vector3D(position));
+      binPacking.ExtremePoints.Add(position, residualSpaces);
+      // Check if the existing extreme points are shadowed by the new point
+      // This is, their residual space fit entirely into the residual space of the new point
+      foreach (var ep in binPacking.ExtremePoints.Where(x => x.Key != position && new Vector3D(x.Key).IsInside(position, residualSpaces)).ToList()) {
+        foreach (var residualSpace in ep.Value) {
+          if (IsWithinResidualSpaceOfAnotherExtremePoint(new Vector3D(ep.Key), residualSpace, position, residualSpaces)) {
             binPacking.ExtremePoints.Remove(ep);
-            binPacking.ResidualSpaces.Remove(ep);
+            break;
           }
+        }          
+      }
+      return true;
+    }
+
+    /// <summary>
+    /// Calculates the residual space for a given bin packing and position.
+    /// It returns the residual space as a tuple which contains the dimensions
+    /// </summary>
+    /// <param name="binPacking"></param>
+    /// <param name="pos"></param>
+    /// <returns>A Tuple(width, Height, Depth)</width></returns>
+    protected override IEnumerable<ResidualSpace> CalculateResidualSpace(BinPacking3D binPacking, Vector3D pos) {
+      var residualSpaces = new List<ResidualSpace>();
+      var residualSpace = new ResidualSpace(CalculateResidualSpaceOld(binPacking, pos));
+      if (!residualSpace.IsZero()) {
+        residualSpaces.Add(residualSpace);
+      }
+      return residualSpaces;
+    }
+
+    protected Tuple<int, int, int> CalculateResidualSpaceOld(BinPacking3D binPacking, Vector3D pos) {
+
+      if (pos == null) {
+        return Tuple.Create(0, 0, 0);
+      }
+      var itemPos = binPacking.Items.Select(x => new {
+        Item = x.Value,
+        Position = binPacking.Positions[x.Key]
+      });
+      Vector3D limit = new Vector3D() {
+        X = binPacking.BinShape.Width,
+        Y = binPacking.BinShape.Height,
+        Z = binPacking.BinShape.Depth
+      };
+
+      if (pos.X < limit.X && pos.Y < limit.Y && pos.Z < limit.Z) {
+        var rightLimit = ProjectRight(binPacking, pos);
+        var upLimit = ProjectUp(binPacking, pos);
+        var forwardLimit = ProjectForward(binPacking, pos);
+        if (rightLimit.X > 0) {
+          limit.X = rightLimit.X;
         }
-        return true;
+        if (upLimit.Y > 0) {
+          limit.Y = upLimit.Y;
+        }
+        if (forwardLimit.Z > 0) {
+          limit.Z = forwardLimit.Z;
+        }
       }
-      return false;
+
+      if (limit.X - pos.X <= 0 || limit.Y - pos.Y <= 0 || limit.Z - pos.Z <= 0) {
+        return Tuple.Create(0, 0, 0);
+      }
+      return Tuple.Create(limit.X - pos.X, limit.Y - pos.Y, limit.Z - pos.Z);
     }
   }
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Edge3D.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Edge3D.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Edge3D.cs	(revision 15554)
@@ -70,5 +70,5 @@
       });
       Vector3D point = l1.Intersect(l2);
-      if (e1.LiesOn(point) && e2.LiesOn(point)) {
+      if (point != null && e1.LiesOn(point) && e2.LiesOn(point)) {
         return point;
       }
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Line3D.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Line3D.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Line3D.cs	(revision 15554)
@@ -9,5 +9,5 @@
   /// A line is given as a point and a directing vector
   /// </summary>
-  internal class Line3D {
+  public class Line3D {
     public Vector3D Point;
     public Vector3D Direction;
@@ -30,7 +30,18 @@
     }
 
+    /// <summary>
+    /// Returns the intersection point of two lines.
+    /// It the lines doesn't intersect it returns null.
+    /// </summary>
+    /// <param name="line"></param>
+    /// <returns></returns>
     public Vector3D Intersect(Line3D line) {
       double r = 0;
       double s = 0;
+
+      // if they have the same source point, this point can be returned.
+      if (this.Point.Equals(line.Point)) {
+        return this.Point;
+      }
 
       if (Direction.X != 0) {
@@ -49,11 +60,9 @@
         s = (this.Point.Z - line.Point.Z) / (double)line.Direction.Z;
       }
-
-      var a = r * this.Direction + this.Point;
-      var b = s * line.Direction + line.Point;
-      var c = a.Equals(b);
-      if (s!=0 && r!=0 && a.Equals(b)) {
-        
-        return a;
+      var p1 = r * this.Direction + this.Point;
+      var p2 = s * line.Direction + line.Point;
+      var c = p1.Equals(p2);
+      if (s!=0 && r!=0 && p1.Equals(p2)) {        
+        return p1;
       }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Plane3D.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Plane3D.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Plane3D.cs	(revision 15554)
@@ -6,14 +6,15 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Geometry {
-  internal enum Side { Top, Left, Bottom, Right, Front, Back }
+  public enum Side { Top, Left, Bottom, Right, Front, Back }
 
   /// <summary>
   /// A plane is given as a point and two directing vectors
   /// </summary>
-  internal class Plane3D {
+  public class Plane3D {
     public Vector3D Point { get; private set; }
     public Vector3D Direction1 { get; private set; }
     public Vector3D Direction2 { get; private set; }
     public Vector3D Normal { get; private set; }
+
     private int rhs;
 
@@ -93,12 +94,28 @@
     }
 
+    /// <summary>
+    /// Returns true if the given point is an element of the current plane
+    /// </summary>
+    /// <param name="point"></param>
+    /// <returns></returns>
     public bool IsElementOf(Vector3D point) {
       return Normal.X * point.X + Normal.Y * point.Y + Normal.Z * point.Z == rhs;
     }
 
+    /// <summary>
+    /// Returns true, if the given line intersects with the current plane
+    /// </summary>
+    /// <param name="line"></param>
+    /// <returns></returns>
     public bool Intersects(Line3D line) {
       return Intersect(line) != null;
     }
 
+    /// <summary>
+    /// Returns the point of intersection of a given line and the current plane.
+    /// It returns null if there is no intersection.
+    /// </summary>
+    /// <param name="line"></param>
+    /// <returns></returns>
     public Vector3D Intersect(Line3D line) {
       var denom = Normal * line.Direction;
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Vector3D.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Vector3D.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Geometry/Vector3D.cs	(revision 15554)
@@ -12,5 +12,9 @@
     public int Z { get; set; }
 
-    public Vector3D() { }
+    public Vector3D() {
+      X = 0;
+      Y = 0;
+      Z = 0;
+    }
     public Vector3D(int x, int y, int z) {
       X = x;
@@ -85,4 +89,8 @@
     }
 
+    public bool IsInside(PackingPosition pos, IEnumerable<ResidualSpace> rs) {
+      return rs.Any(x => IsInside(pos, x));
+    }
+
     public static int operator *(Vector3D a, Vector3D b) {
       return a.X * b.X + a.Y * b.Y + a.Z * b.Z;
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IOperator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IOperator.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IOperator.cs	(revision 15554)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Problems.BinPacking3D.Encoding;
+using HeuristicLab.Problems.BinPacking3D.Evaluators;
+
+namespace HeuristicLab.Problems.BinPacking3D {
+  public interface IOperator<TSol> : IItem {
+    ILookupParameter<ReadOnlyItemList<PackingItem>> ItemsParameter { get; }
+    ILookupParameter<PackingShape> BinShapeParameter { get; }
+    ILookupParameter<IDecoder<TSol>> DecoderParameter { get; }
+    ILookupParameter<IEvaluator> SolutionEvaluatorParameter { get; }
+    ILookupParameter<BoolValue> UseStackingConstraintsParameter { get; }
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPacker.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPacker.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPacker.cs	(revision 15554)
@@ -33,12 +33,6 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Packer {
-  public abstract class BinPacker : Item {
-
-    /*
-    [Storable]
-    IPositionFinder PositionFinder
+  internal abstract class BinPacker : Item, IBinPacker {
     
-    */
-
     #region Constructors for HEAL
 
@@ -49,5 +43,4 @@
     protected BinPacker(BinPacker original, Cloner cloner) 
       : base(original, cloner) {
-      //this.PositionFinder = original.PositionFinder;
     }
 
@@ -99,5 +92,7 @@
 
       // The extremepoints are sortet by Y / Z / X
-      return packingBin.ExtremePoints.Where(x => packingBin.IsPositionFeasible(newItem, x, useStackingConstraints)).FirstOrDefault();
+      var newPosition = packingBin.ExtremePoints.Where(x => packingBin.IsPositionFeasible(newItem, x.Key, useStackingConstraints)).FirstOrDefault();
+     
+      return newPosition.Key;
     }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFactory.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFactory.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFactory.cs	(revision 15554)
@@ -17,6 +17,6 @@
     /// <param name="fittingMethod"></param>
     /// <returns>Returns a new BinPacker depending on the given fitting method</returns>
-    public static BinPacker CreateBinPacker(FittingMethod fittingMethod) {
-      BinPacker binPacker = null;
+    public static IBinPacker CreateBinPacker(FittingMethod fittingMethod) {
+      IBinPacker binPacker = null;
       switch (fittingMethod) {
         case FittingMethod.FirstFit:
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFirstFit.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFirstFit.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFirstFit.cs	(revision 15554)
@@ -32,5 +32,5 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Packer {
-  public class BinPackerFirstFit : BinPacker {
+  internal class BinPackerFirstFit : BinPacker {
     #region Constructors for HEAL
     [StorableConstructor]
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFreeVolumeBestFit.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFreeVolumeBestFit.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFreeVolumeBestFit.cs	(revision 15554)
@@ -32,5 +32,5 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Packer {
-  public class BinPackerFreeVolumeBestFit : BinPacker {
+  internal class BinPackerFreeVolumeBestFit : BinPacker {
     
     #region Constructors for HEAL
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerResidualSpaceBestFit.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerResidualSpaceBestFit.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerResidualSpaceBestFit.cs	(revision 15554)
@@ -32,5 +32,5 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Packer {
-  public class BinPackerResidualSpaceBestFit : BinPacker {
+  internal class BinPackerResidualSpaceBestFit : BinPacker {
 
     #region Constructors for HEAL
@@ -55,8 +55,8 @@
     /// </summary>
     /// <returns>Returns a collection of bin packing 3d objects. Each object represents a bin and the packed items</returns>
-    public override IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, ExtremePointCreationMethod epGenerationMethod, bool useStackingConstraints) {
+    public override IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, bool useStackingConstraints) {
       IList<BinPacking3D> packingList = new List<BinPacking3D>();
       IList<int> remainingIds = new List<int>(sortedItems);
-      IExtremePointCreator extremePointCreator = ExtremePointCreatorFactory.CreateExtremePointCreator(epGenerationMethod, useStackingConstraints);
+      IExtremePointCreator extremePointCreator = ExtremePointCreatorFactory.CreateExtremePointCreator(epCreationMethod, useStackingConstraints);
       bool rotated = false;
 
@@ -100,10 +100,12 @@
       var residualSpacePoints = new List<Tuple<BinPacking3D, PackingPosition, int>>();
       foreach (BinPacking3D bp in packingList) {
-        foreach (var ep in bp.ExtremePoints) {
-          var rs = bp.ResidualSpaces[ep];
-          if (rs.Width < item.Width || rs.Height < item.Height || rs.Depth < item.Depth) {
+        foreach (var extremPoints in bp.ExtremePoints) {
+          var ep = extremPoints.Key;
+          var residualSpaces = extremPoints.Value.Where(rs => rs.Width < item.Width || rs.Height < item.Height || rs.Depth < item.Depth);
+          if (residualSpaces.Count() <= 0) {
             continue;
           }
-          residualSpacePoints.Add(Tuple.Create(bp, ep, CalculateResidualMerit(rs, item, ep)));
+          int merit = residualSpaces.Max(rs => CalculateResidualMerit(rs, item, ep));
+          residualSpacePoints.Add(Tuple.Create(bp, ep, merit));
         }
       }
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/IBinPacker.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/IBinPacker.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/IBinPacker.cs	(revision 15554)
@@ -0,0 +1,21 @@
+﻿using HeuristicLab.Encodings.PermutationEncoding;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Problems.BinPacking3D.Packer {
+  public interface IBinPacker {
+    /// <summary>
+    /// Packs all items of the bin packer and returns a collection of BinPacking3D objects
+    /// </summary>
+    /// <param name="sortedItems">Permutation of items sorted by a sorting method. The value of each permutation index references to the index of the items list</param>
+    /// <param name="binShape">Bin for storing the items</param>
+    /// <param name="items">A list of packing items which should be assigned to a bin</param>
+    /// <param name="useStackingConstraints">Flag for using stacking constraints</param>
+    /// <returns>Returns a collection of bin packing 3d objects. Each object represents a bin and the packed items</returns>
+    IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, ExtremePointCreationMethod epCreationMethod, bool useStackingConstraints);
+
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs	(revision 15554)
@@ -75,30 +75,5 @@
       return base.GetHashCode() + 13 * X + 17 * Y + 23 * Z;
     }
-
-    [Obsolete]
-    public static PackingPosition MoveLeft(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X - 1, original.Y, original.Z, original.Rotated);
-    }
-    [Obsolete]
-    public static PackingPosition MoveDown(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X, original.Y - 1, original.Z, original.Rotated);
-    }
-    [Obsolete]
-    public static PackingPosition MoveBack(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X, original.Y, original.Z - 1, original.Rotated);
-    }
-    [Obsolete]
-    public static PackingPosition MoveRight(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X + 1, original.Y, original.Z, original.Rotated);
-    }
-    [Obsolete]
-    public static PackingPosition MoveUp(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X, original.Y + 1, original.Z, original.Rotated);
-    }
-    [Obsolete]
-    public static PackingPosition MoveFront(PackingPosition original) {
-      return new PackingPosition(original.AssignedBin, original.X, original.Y, original.Z + 1, original.Rotated);
-    }
-
+    
     #region IComparable<PackingPosition> Members
 
@@ -115,13 +90,5 @@
       if (result == 0)
         result = X.CompareTo(other.X);
-      /*
-      int result = Z.CompareTo(other.Z);
-      if (result == 0)
-        result = X.CompareTo(other.X);
-      if (result == 0)
-        result = Y.CompareTo(other.Y);
-      */
       return result;
-
     }
 
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/IResidualSpaceCalculator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/IResidualSpaceCalculator.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/IResidualSpaceCalculator.cs	(revision 15554)
@@ -11,4 +11,5 @@
     /// <summary>
     /// Calculates all available residual spaces for a given point and returns them packed in a collection.
+    /// The returned collection has zero elements if the residual space is zero
     /// </summary>
     /// <param name="binPacking"></param>
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculator.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculator.cs	(revision 15554)
@@ -10,5 +10,5 @@
 
     internal ResidualSpaceCalculator() {}
-
+    
     public IEnumerable<ResidualSpace> CalculateResidualSpaces(BinPacking3D binPacking, Vector3D point) {
       IList<ResidualSpace> residualSpaces = new List<ResidualSpace>();
@@ -17,11 +17,13 @@
       var rs3 = CalculateYXZ(binPacking, point);
 
-      residualSpaces.Add(rs1);
-
-
-      if (!residualSpaces.Any(rs => rs.Equals(rs2))) {
+      if (!rs1.IsZero()) {
+        residualSpaces.Add(rs1);
+      }     
+
+
+      if (!rs2.IsZero() && !residualSpaces.Any(rs => rs.Equals(rs2))) {
         residualSpaces.Add(rs2);
       }
-      if (!residualSpaces.Any(rs => rs.Equals(rs3))) {
+      if (!rs3.IsZero() && !residualSpaces.Any(rs => rs.Equals(rs3))) {
         residualSpaces.Add(rs3);
       }
@@ -56,4 +58,12 @@
     }
     
+    /// <summary>
+    /// Returnst true if a given residual space and item overlaps at the x-axis
+    /// </summary>
+    /// <param name="point"></param>
+    /// <param name="residualSpace"></param>
+    /// <param name="position"></param>
+    /// <param name="item"></param>
+    /// <returns></returns>
     private bool OverlapsX(Vector3D point, ResidualSpace residualSpace, PackingPosition position, PackingItem item) {
       if (point.X > position.X && point.X >= position.X + item.Width) {
@@ -66,5 +76,12 @@
       return true;
     }
-    
+
+    /// <summary>
+    /// Returnst true if a given residual space and item overlaps at the y-axis
+    /// </summary>
+    /// <param name="point"></param>
+    /// <param name="residualSpace"></param>
+    /// <param name="position"></param>
+    /// <param name="item"></param>
     private bool OverlapsY(Vector3D point, ResidualSpace residualSpace, PackingPosition position, PackingItem item) {
       if (point.Y > position.Y && point.Y >= position.Y + item.Height) {
@@ -78,4 +95,11 @@
     }
 
+    /// <summary>
+    /// Returnst true if a given residual space and item overlaps at the z-axis
+    /// </summary>
+    /// <param name="point"></param>
+    /// <param name="residualSpace"></param>
+    /// <param name="position"></param>
+    /// <param name="item"></param>
     private bool OverlapsZ(Vector3D point, ResidualSpace residualSpace, PackingPosition position, PackingItem item) {
       if (point.Z > position.Z && point.Z >= position.Z + item.Depth) {
@@ -90,4 +114,5 @@
 
     private bool OverlapsOnRight(Vector3D point, ResidualSpace residualSpace, PackingPosition position, PackingItem item) {
+      // if point.x >= position.x, the residual space would be located on the left side!
       if (point.X >= position.X) {
         return false;
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Sorting/IOperator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Sorting/IOperator.cs	(revision 15553)
+++ 	(revision )
@@ -1,35 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Joseph Helm and Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Problems.BinPacking3D.Encoding;
-using HeuristicLab.Problems.BinPacking3D.Evaluators;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  public interface IOperator<TSol> : IItem {
-    ILookupParameter<ReadOnlyItemList<PackingItem>> ItemsParameter { get; }
-    ILookupParameter<PackingShape> BinShapeParameter { get; }
-    ILookupParameter<IDecoder<TSol>> DecoderParameter { get; }
-    ILookupParameter<IEvaluator> SolutionEvaluatorParameter { get; }
-    ILookupParameter<BoolValue> UseStackingConstraintsParameter { get; }
-  }
-}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/HeuristicLab.Problems.BinPacking-3.3.csproj
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/HeuristicLab.Problems.BinPacking-3.3.csproj	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/HeuristicLab.Problems.BinPacking-3.3.csproj	(revision 15554)
@@ -130,9 +130,10 @@
     <Compile Include="3D\Encoding\IDecoder.cs" />
     <Compile Include="3D\Evaluators\IEvaluator.cs" />
+    <Compile Include="3D\Packer\IBinPacker.cs" />
     <Compile Include="3D\ResidualSpace.cs" />
     <Compile Include="3D\ResidualSpaceCalculation\IResidualSpaceCalculator.cs" />
     <Compile Include="3D\ResidualSpaceCalculation\ResidualSpaceCalculator.cs" />
     <Compile Include="3D\ResidualSpaceCalculation\ResidualSpaceCalculatorFactory.cs" />
-    <Compile Include="3D\Sorting\IOperator.cs" />
+    <Compile Include="3D\IOperator.cs" />
     <Compile Include="3D\Evaluators\MoveEvaluatorBase.cs" />
     <Compile Include="3D\PackingItem.cs" />
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Algorithms/ExtremePointAlgorithmTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Algorithms/ExtremePointAlgorithmTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Algorithms/ExtremePointAlgorithmTest.cs	(revision 15554)
@@ -0,0 +1,100 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D;
+using System.Collections.Generic;
+
+using HeuristicLab.Problems.BinPacking._3D.Utils.Tests;
+using System.Threading;
+using System.Linq;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Algorithms.Tests {
+  [TestClass]
+  public class ExtremePointAlgorithmTest {
+
+    private PackingShape _packingShape1;
+    private PackingShape _packingShape2;
+    private PackingShape _packingShape3;
+    private IList<PackingItem> _items;
+    private ExtremePointAlgorithm _extremPointAlgorithm;
+
+    [TestInitialize]
+    public void Initializes() {
+      _packingShape1 = new PackingShape(19, 19, 19);
+      _packingShape2 = new PackingShape(18, 18, 18);
+      _packingShape3 = new PackingShape(20, 20, 20);
+      _items = new List<PackingItem>();
+
+      _items.Add(new PackingItem(8, 10, 10, _packingShape1, 1000, 1)); // 0,  V = 800,  A =  80, h = 10
+      _items.Add(new PackingItem(10, 8, 10, _packingShape1, 1000, 2)); // 1,  V = 800,  A = 100, h =  8
+      _items.Add(new PackingItem(10, 10, 8, _packingShape1, 1000, 3)); // 2,  V = 800,  A =  80, h = 10
+      _items.Add(new PackingItem(8, 8, 10, _packingShape1, 1000, 4)); // 3,   V = 640,  A =  80, h =  8
+      _items.Add(new PackingItem(10, 8, 8, _packingShape1, 1000, 0)); // 4,   V = 640,  A =  80, h =  8
+      _items.Add(new PackingItem(8, 10, 8, _packingShape1, 1000, 1)); // 5,   V = 640,  A =  64, h = 10  
+      _items.Add(new PackingItem(8, 8, 8, _packingShape1, 1000, 2)); // 6,    V = 512,  A =  64, h =  8
+
+      _items.Add(new PackingItem(10, 10, 10, _packingShape1, 1000, 3)); // 7, V = 1000, A = 100, h = 10
+
+      _items.Add(new PackingItem(9, 10, 10, _packingShape1, 1000, 4)); // 8,  V = 900,  A =  90, h = 10
+      _items.Add(new PackingItem(10, 9, 10, _packingShape1, 1000, 0)); // 9,  V = 900,  A = 100, h =  9
+      _items.Add(new PackingItem(10, 10, 9, _packingShape1, 1000, 1)); // 10, V = 900,  A =  90, h = 10
+      _items.Add(new PackingItem(9, 9, 10, _packingShape1, 1000, 2)); // 11,  V = 810,  A =  90, h =  9
+      _items.Add(new PackingItem(10, 9, 9, _packingShape1, 1000, 3)); // 12,  V = 810,  A =  90, h =  9
+      _items.Add(new PackingItem(9, 10, 9, _packingShape1, 1000, 4)); // 13,  V = 810,  A =  81, h = 10
+      _items.Add(new PackingItem(9, 9, 9, _packingShape1, 1000, 0)); // 14,   V = 729,  A =  81, h =  9
+
+      _extremPointAlgorithm = new ExtremePointAlgorithm();
+    }
+
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithm() {
+       
+      IList<BinPacking3D.PackingPosition> positionsBin0 = new List<BinPacking3D.PackingPosition>() {
+        new BinPacking3D.PackingPosition(0, 0,0,0),
+        new BinPacking3D.PackingPosition(0, 8,0,0),
+        new BinPacking3D.PackingPosition(0, 0,0,10),
+        new BinPacking3D.PackingPosition(0, 10,0,10),
+        new BinPacking3D.PackingPosition(0, 8,8,0),
+        new BinPacking3D.PackingPosition(0, 0,10,0),
+        new BinPacking3D.PackingPosition(0, 0,10,8),
+        new BinPacking3D.PackingPosition(0, 8,10,8),
+      };
+
+      IList<BinPacking3D.PackingPosition> positionsBin1 = new List<BinPacking3D.PackingPosition>() {
+        new BinPacking3D.PackingPosition(1, 0,0,0),
+        new BinPacking3D.PackingPosition(1, 9,0,0),
+        new BinPacking3D.PackingPosition(1, 0,0,10),
+        new BinPacking3D.PackingPosition(1, 10,0,10),
+        new BinPacking3D.PackingPosition(1, 9,9,0),
+        new BinPacking3D.PackingPosition(1, 0,10,0),
+        new BinPacking3D.PackingPosition(1, 0,10,9)
+      };
+
+      object[] parameters = new object[] { _packingShape3, _items, new SortingMethod[] { SortingMethod.Given }, new FittingMethod[] { FittingMethod.FirstFit }, new CancellationToken() };
+      _extremPointAlgorithm.SortingMethodParameter.Value.Value = SortingMethod.Given;
+      _extremPointAlgorithm.FittingMethodParameter.Value.Value = FittingMethod.FirstFit;
+      _extremPointAlgorithm.ExtremePointCreationMethodParameter.Value.Value = ExtremePointCreationMethod.PointProjection;
+      _extremPointAlgorithm.SortByMaterialParameter.Value.Value = false;
+      var result = TestUtils.InvokeMethod(typeof(ExtremePointAlgorithm), _extremPointAlgorithm, "GetBest", parameters) as Tuple<Solution, double, SortingMethod?, FittingMethod?>;
+
+      int i = 0;
+      foreach (var item in result.Item1.Bins[0].Positions.Values) {
+        Assert.AreEqual(positionsBin0[i].X, item.X);
+        Assert.AreEqual(positionsBin0[i].Y, item.Y);
+        Assert.AreEqual(positionsBin0[i].Z, item.Z);
+        i++;
+      }
+
+      i = 0;
+      foreach (var item in result.Item1.Bins[1].Positions.Values) {
+        Assert.AreEqual(positionsBin1[i].X, item.X);
+        Assert.AreEqual(positionsBin1[i].Y, item.Y);
+        Assert.AreEqual(positionsBin1[i].Z, item.Z);
+        i++;
+      }
+    }
+  }
+}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointAlgorithmTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointAlgorithmTest.cs	(revision 15553)
+++ 	(revision )
@@ -1,98 +1,0 @@
-﻿using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HeuristicLab.Problems.BinPacking3D;
-using System.Collections.Generic;
-
-using HeuristicLab.Problems.BinPacking._3D.Utils.Tests;
-using System.Threading;
-using System.Linq;
-
-namespace HeuristicLab.Problems.BinPacking._3D.Tests {
-  [TestClass]
-  public class ExtremePointAlgorithmTest {
-
-    private PackingShape _packingShape1;
-    private PackingShape _packingShape2;
-    private PackingShape _packingShape3;
-    private IList<PackingItem> _items;
-    private ExtremePointAlgorithm _extremPointAlgorithm;
-
-    [TestInitialize]
-    public void Initializes() {
-      _packingShape1 = new PackingShape(19, 19, 19);
-      _packingShape2 = new PackingShape(18, 18, 18);
-      _packingShape3 = new PackingShape(20, 20, 20);
-      _items = new List<PackingItem>();
-
-      _items.Add(new PackingItem(8, 10, 10, _packingShape1, 1000, 1)); // 0,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(10, 8, 10, _packingShape1, 1000, 2)); // 1,  V = 800,  A = 100, h =  8
-      _items.Add(new PackingItem(10, 10, 8, _packingShape1, 1000, 3)); // 2,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(8, 8, 10, _packingShape1, 1000, 4)); // 3,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(10, 8, 8, _packingShape1, 1000, 0)); // 4,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(8, 10, 8, _packingShape1, 1000, 1)); // 5,   V = 640,  A =  64, h = 10  
-      _items.Add(new PackingItem(8, 8, 8, _packingShape1, 1000, 2)); // 6,    V = 512,  A =  64, h =  8
-
-      _items.Add(new PackingItem(10, 10, 10, _packingShape1, 1000, 3)); // 7, V = 1000, A = 100, h = 10
-
-      _items.Add(new PackingItem(9, 10, 10, _packingShape1, 1000, 4)); // 8,  V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(10, 9, 10, _packingShape1, 1000, 0)); // 9,  V = 900,  A = 100, h =  9
-      _items.Add(new PackingItem(10, 10, 9, _packingShape1, 1000, 1)); // 10, V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(9, 9, 10, _packingShape1, 1000, 2)); // 11,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(10, 9, 9, _packingShape1, 1000, 3)); // 12,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(9, 10, 9, _packingShape1, 1000, 4)); // 13,  V = 810,  A =  81, h = 10
-      _items.Add(new PackingItem(9, 9, 9, _packingShape1, 1000, 0)); // 14,   V = 729,  A =  81, h =  9
-
-      _extremPointAlgorithm = new ExtremePointAlgorithm();
-    }
-
-
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithm() {
-       
-      IList<BinPacking3D.PackingPosition> positionsBin0 = new List<BinPacking3D.PackingPosition>() {
-        new BinPacking3D.PackingPosition(0, 0,0,0),
-        new BinPacking3D.PackingPosition(0, 8,0,0),
-        new BinPacking3D.PackingPosition(0, 0,0,10),
-        new BinPacking3D.PackingPosition(0, 10,0,10),
-        new BinPacking3D.PackingPosition(0, 8,8,0),
-        new BinPacking3D.PackingPosition(0, 0,10,0),
-        new BinPacking3D.PackingPosition(0, 0,10,8),
-        new BinPacking3D.PackingPosition(0, 8,10,8),
-      };
-
-      IList<BinPacking3D.PackingPosition> positionsBin1 = new List<BinPacking3D.PackingPosition>() {
-        new BinPacking3D.PackingPosition(1, 0,0,0),
-        new BinPacking3D.PackingPosition(1, 9,0,0),
-        new BinPacking3D.PackingPosition(1, 0,0,10),
-        new BinPacking3D.PackingPosition(1, 10,0,10),
-        new BinPacking3D.PackingPosition(1, 9,9,0),
-        new BinPacking3D.PackingPosition(1, 0,10,0),
-        new BinPacking3D.PackingPosition(1, 0,10,9)
-      };
-
-      object[] parameters = new object[] { _packingShape3, _items, new SortingMethod[] { SortingMethod.Given }, new FittingMethod[] { FittingMethod.FirstFit }, new CancellationToken() };
-      _extremPointAlgorithm.SortingMethodParameter.Value.Value = SortingMethod.Given;
-      _extremPointAlgorithm.FittingMethodParameter.Value.Value = FittingMethod.FirstFit;
-      _extremPointAlgorithm.SortByMaterialParameter.Value.Value = false;
-      var result = TestUtils.InvokeMethod(typeof(ExtremePointAlgorithm), _extremPointAlgorithm, "GetBest", parameters) as Tuple<Solution, double, SortingMethod?, FittingMethod?>;
-
-      int i = 0;
-      foreach (var item in result.Item1.Bins[0].Positions.Values) {
-        Assert.AreEqual(positionsBin0[i].X, item.X);
-        Assert.AreEqual(positionsBin0[i].Y, item.Y);
-        Assert.AreEqual(positionsBin0[i].Z, item.Z);
-        i++;
-      }
-
-      i = 0;
-      foreach (var item in result.Item1.Bins[1].Positions.Values) {
-        Assert.AreEqual(positionsBin1[i].X, item.X);
-        Assert.AreEqual(positionsBin1[i].Y, item.Y);
-        Assert.AreEqual(positionsBin1[i].Z, item.Z);
-        i++;
-      }
-    }
-  }
-}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointCreation/TestLineProjectionBasedEPCreator.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointCreation/TestLineProjectionBasedEPCreator.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointCreation/TestLineProjectionBasedEPCreator.cs	(revision 15554)
@@ -0,0 +1,126 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.ExtremePointCreation;
+
+namespace HeuristicLab.Problems.BinPacking._3D.ExtremePointCreation.Tests {
+
+  [TestClass]
+  public class TestLineProjectionBasedEPCreator {
+
+    BinPacking3D.BinPacking3D _binPacking1;
+    BinPacking3D.BinPacking3D _binPacking2;
+    BinPacking3D.BinPacking3D _binPacking3;
+    BinPacking3D.BinPacking3D _binPacking4;
+
+    BinPacking3D.PackingItem _item1;
+    BinPacking3D.PackingItem _item2;
+    BinPacking3D.PackingItem _item3;
+    BinPacking3D.PackingItem _item4;
+
+    BinPacking3D.PackingPosition _pos1;
+    BinPacking3D.PackingPosition _pos2;
+    BinPacking3D.PackingPosition _pos3;
+    BinPacking3D.PackingPosition _pos4;
+
+    IExtremePointCreator _creator;
+
+    [TestInitialize]
+    public void Initialize() {
+      _creator = ExtremePointCreatorFactory.CreateExtremePointCreator(BinPacking3D.ExtremePointCreationMethod.LineProjection, false);
+      var packingShape = new BinPacking3D.PackingShape(20, 20, 20);
+      _item1 = new BinPacking3D.PackingItem(8, 4, 8, packingShape);
+      _item2 = new BinPacking3D.PackingItem(4, 10, 4, packingShape);
+      _item3 = new BinPacking3D.PackingItem(8, 8, 8, packingShape);
+      _item4 = new BinPacking3D.PackingItem(2, 2, 20, packingShape);
+
+      _pos1 = new BinPacking3D.PackingPosition(0, 0, 0, 0);
+      _pos2 = new BinPacking3D.PackingPosition(0, 8, 0, 0);
+      _pos3 = new BinPacking3D.PackingPosition(0, 12, 0, 0);
+      _pos4 = new BinPacking3D.PackingPosition(0, 0, 4, 0);
+
+      _binPacking1 = new BinPacking3D.BinPacking3D(packingShape);
+
+      _binPacking1.PackItem(0, _item1, _pos1);
+
+      _binPacking2 = _binPacking1.Clone() as BinPacking3D.BinPacking3D;
+      _binPacking2.PackItem(1, _item2, _pos2);
+
+      _binPacking3 = _binPacking2.Clone() as BinPacking3D.BinPacking3D;
+      _binPacking3.PackItem(2, _item3, _pos3);
+
+      _binPacking4 = _binPacking3.Clone() as BinPacking3D.BinPacking3D;
+      _binPacking4.PackItem(3, _item4, _pos4);
+
+      Assert.AreEqual(1, _binPacking1.Items.Count);
+      Assert.AreEqual(2, _binPacking2.Items.Count);
+      Assert.AreEqual(3, _binPacking3.Items.Count);
+      Assert.AreEqual(4, _binPacking4.Items.Count);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestUpdateExtremePoints1() {
+
+      _creator.UpdateBinPacking(_binPacking1, _item1, _pos1);
+      Assert.AreEqual(3, _binPacking1.ExtremePoints.Count);
+      Assert.IsTrue(_binPacking1.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 0, 0)));
+      Assert.IsTrue(_binPacking1.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 4, 0)));
+      Assert.IsTrue(_binPacking1.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 0, 8)));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestUpdateExtremePoints2() {
+      _creator.UpdateBinPacking(_binPacking2, _item2, _pos2);
+      Assert.AreEqual(7, _binPacking2.ExtremePoints.Count);
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 12, 0, 0)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 0, 4)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 0, 8)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 4, 0)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 4, 4)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 10, 0)));
+      Assert.IsTrue(_binPacking2.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 10, 0)));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestUpdateExtremePoints3() {
+      _creator.UpdateBinPacking(_binPacking3, _item3, _pos3);
+      Assert.AreEqual(8, _binPacking3.ExtremePoints.Count);
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 0, 4)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 0, 8)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 4, 0)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 4, 4)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 12, 8, 0)));
+
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 8, 4)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 10, 0)));
+      Assert.IsTrue(_binPacking3.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 10, 0)));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestUpdateExtremePoints4() {
+      _creator.UpdateBinPacking(_binPacking4, _item4, _pos4);
+      Assert.AreEqual(12, _binPacking4.ExtremePoints.Count);
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 0, 4)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 0, 8)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 2, 0, 8)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 2, 4, 0)));
+
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 2, 4, 4)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 6, 0)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 6, 4)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 6, 8)));
+
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 12, 8, 0)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 8, 4)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 0, 10, 0)));
+      Assert.IsTrue(_binPacking4.ExtremePoints.ContainsKey(new BinPacking3D.PackingPosition(0, 8, 10, 0)));
+    }
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Edge3DTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Edge3DTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Edge3DTest.cs	(revision 15554)
@@ -0,0 +1,117 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.Geometry;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Geometry.Test {
+  [TestClass]
+  public class Edge3DTest {
+
+    Edge3D _edge1;
+    Edge3D _edge2;
+    Edge3D _edge3;
+    Edge3D _edge4;
+    Edge3D _edge5;
+    Edge3D _edge6;
+    Edge3D _edge7;
+    Edge3D _edge8;
+    Edge3D _edge9;
+
+    Vector3D _point1;
+    Vector3D _point2;
+    Vector3D _point3;
+    Vector3D _point4;
+    Vector3D _point5;
+    Vector3D _point6;
+
+    [TestInitialize]
+    public void Initialize() {
+      _edge1 = new Edge3D(new Vector3D(0, 0, 0), new Vector3D(10, 0, 0));
+      _edge2 = new Edge3D(new Vector3D(0, 0, 0), new Vector3D(0, 10, 0));
+      _edge3 = new Edge3D(new Vector3D(0, 0, 0), new Vector3D(0, 0, 10));
+
+      _edge4 = new Edge3D(new Vector3D(-10, 2, 2), new Vector3D(10, 2, 2));
+      _edge5 = new Edge3D(new Vector3D(2, -10, 2), new Vector3D(2, 10, 2));
+      _edge6 = new Edge3D(new Vector3D(2, 2, -10), new Vector3D(2, 2, 10));
+
+      _edge7 = new Edge3D(new Vector3D(-10, 5, 5), new Vector3D(10, 5, 5));
+      _edge8 = new Edge3D(new Vector3D(5, -10, 5), new Vector3D(5, 10, 5));
+      _edge9 = new Edge3D(new Vector3D(5, 5, -10), new Vector3D(5, 5, 10));
+
+      _point1 = new Vector3D(3, 0, 0);
+      _point2 = new Vector3D(0, 3, 0);
+      _point3 = new Vector3D(0, 0, 3);
+
+      _point4 = new Vector3D(5, 5, 5);
+      _point5 = new Vector3D(2, 2, 2);
+      _point6 = new Vector3D(0, 0, 0);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestConstructors() {
+      var e1 = new Edge3D() {
+        Start = new Vector3D(10, 0, 0),
+        End = new Vector3D(10, 5, 0)
+      };
+      var e2 = new Edge3D(new Vector3D(10, 0, 0), new Vector3D(10, 5, 0));
+      var e3 = new Edge3D(new BinPacking3D.PackingPosition(0, 10, 0, 0), new BinPacking3D.PackingPosition(0, 10, 5, 0));
+
+      Assert.AreEqual(e1.Start, e2.Start);
+      Assert.AreEqual(e1.End, e2.End);
+      Assert.AreEqual(e1.Start, e3.Start);
+      Assert.AreEqual(e1.End, e3.End);
+      Assert.AreEqual(e3.Start, e2.Start);
+      Assert.AreEqual(e3.End, e2.End);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestLiesOn() {
+      Assert.IsTrue(_edge1.LiesOn(_point1));
+      Assert.IsFalse(_edge1.LiesOn(_point4));
+      Assert.IsTrue(_edge3.LiesOn(_point6));
+      Assert.IsFalse(_edge2.LiesOn(_point5));
+      Assert.IsTrue(_edge4.LiesOn(_point5));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersects() {
+      Assert.IsNull(_edge1.Intersects(_edge4));
+      Assert.IsNull(_edge4.Intersects(_edge1));
+      Assert.IsNull(_edge7.Intersects(_edge5));
+      Assert.IsNull(_edge8.Intersects(_edge6));
+
+      Assert.IsNotNull(_edge1.Intersects(_edge2));
+      Assert.AreEqual(_point6, _edge1.Intersects(_edge2));
+      Assert.IsNotNull(_edge5.Intersects(_edge5));
+      Assert.AreEqual(_point5, _edge5.Intersects(_edge6));
+      Assert.IsNotNull(_edge8.Intersects(_edge7));
+      Assert.AreEqual(_point4, _edge8.Intersects(_edge7));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestStaticIntersects() {
+      Assert.IsNull(Edge3D.Intersects(_edge1, _edge4));
+      Assert.IsNull(Edge3D.Intersects(_edge4, _edge1));
+      Assert.IsNull(Edge3D.Intersects(_edge7, _edge5));
+      Assert.IsNull(Edge3D.Intersects(_edge8, _edge6));
+      
+      Assert.IsNotNull(Edge3D.Intersects(new Edge3D(new Vector3D(0, 0, 0), new Vector3D(10, 0, 0)), new Edge3D(new Vector3D(0, 0, 0), new Vector3D(0, 10, 0))));
+      Assert.IsNotNull(Edge3D.Intersects(new Edge3D(new Vector3D(-10, 0, 0), new Vector3D(0, 0, 0)), new Edge3D(new Vector3D(0, -10, 0), new Vector3D(0, 0, 0))));
+
+      Assert.IsNotNull(Edge3D.Intersects(_edge1, _edge2));
+      Assert.AreEqual(_point6, Edge3D.Intersects(_edge1, _edge2));
+      Assert.IsNotNull(Edge3D.Intersects(_edge5, _edge5));
+      Assert.AreEqual(_point5, Edge3D.Intersects(_edge5, _edge6));
+      Assert.IsNotNull(Edge3D.Intersects(_edge8, _edge7));
+      Assert.AreEqual(_point4, Edge3D.Intersects(_edge8, _edge7));
+    }    
+  }
+}
+
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Line3DTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Line3DTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Line3DTest.cs	(revision 15554)
@@ -0,0 +1,112 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.Geometry;
+using HeuristicLab.Problems.BinPacking3D;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Geometry.Test {
+  [TestClass]
+  public class Line3DTest {
+    Line3D _line1;
+    Line3D _line2;
+    Line3D _line3;
+    Line3D _line4;
+    Line3D _line5;
+    Line3D _line6;
+
+    Vector3D _point1;
+    Vector3D _point2;
+    Vector3D _point3;
+    Vector3D _point4;
+    Vector3D _point5;
+    Vector3D _point6;
+
+    Plane3D _plane1;
+    Plane3D _plane2;
+    Plane3D _plane3;
+
+    [TestInitialize]
+    public void Initialize() {
+      _line1 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(10, 0, 0));
+      _line2 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(0, 10, 0));
+      _line3 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(0, 0, 10));
+
+      _line4 = new Line3D(new Vector3D(-10, 2, 2), new Vector3D(10, 0, 0));
+      _line5 = new Line3D(new Vector3D(2, -10, 2), new Vector3D(0, 10, 0));
+      _line6 = new Line3D(new Vector3D(2, 2, -10), new Vector3D(0, 0, 10));
+
+      _point1 = new Vector3D(3, 0, 0);
+      _point2 = new Vector3D(0, 3, 0);
+      _point3 = new Vector3D(0, 0, 3);
+
+      _point4 = new Vector3D(5, 5, 5);
+      _point5 = new Vector3D(2, 2, 2);
+      _point6 = new Vector3D(0, 0, 0);
+
+      _plane1 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Top);
+      _plane2 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Right);
+      _plane3 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Front);
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersectsPlane() {
+      Assert.IsFalse(_line1.Intersects(_plane1));
+      Assert.IsTrue(_line2.Intersects(_plane1));
+      Assert.IsFalse(_line3.Intersects(_plane1));
+
+      Assert.IsTrue(_line1.Intersects(_plane2));
+      Assert.IsFalse(_line2.Intersects(_plane2));
+      Assert.IsFalse(_line3.Intersects(_plane2));
+
+      Assert.IsFalse(_line1.Intersects(_plane3));
+      Assert.IsFalse(_line2.Intersects(_plane3));
+      Assert.IsTrue(_line3.Intersects(_plane3));
+
+      Assert.IsTrue((new Line3D(new Vector3D(-1, -2, 2), new Vector3D(1, 3, 1))).Intersects(_plane1));
+      Assert.IsFalse((new Line3D(new Vector3D(-1, -2, 2), new Vector3D(-1, -3, 1))).Intersects(_plane1));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersectPlane() {
+      Assert.IsNull(_line1.Intersect(_plane1));
+      Assert.AreEqual(new Vector3D(0, 10, 0), _line2.Intersect(_plane1));
+      Assert.IsNull(_line3.Intersect(_plane1));
+
+      Assert.AreEqual(new Vector3D(10, 0, 0), _line1.Intersect(_plane2));
+      Assert.IsNull(_line2.Intersect(_plane2));
+      Assert.IsNull(_line3.Intersect(_plane2));
+
+      Assert.IsNull(_line1.Intersect(_plane3));
+      Assert.IsNull(_line2.Intersect(_plane3));
+      Assert.AreEqual(new Vector3D(0, 0, 10), _line3.Intersect(_plane3));
+      Assert.AreEqual(new Vector3D(3, 10, 6), (new Line3D(new Vector3D(-1, -2, 2), new Vector3D(1, 3, 1))).Intersect(_plane1));
+      Assert.IsNull((new Line3D(new Vector3D(-1, -2, 2), new Vector3D(-1, -3, 1))).Intersect(_plane1));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersectLine() {
+      Assert.IsNull(_line1.Intersect(_line4));
+      Assert.IsNull(_line1.Intersect(_line5));
+      Assert.IsNull(_line1.Intersect(_line6));
+
+      Assert.IsNotNull(_line1.Intersect(_line1));
+      Assert.IsNotNull(_line1.Intersect(_line2));
+      Assert.IsNotNull(_line1.Intersect(_line3));
+
+      Assert.IsNotNull(_line4.Intersect(_line5));
+      Assert.IsNotNull(_line4.Intersect(_line6));
+
+      Assert.IsTrue(_line1.Intersect(_line1).Equals(_point6));
+      Assert.IsTrue(_line1.Intersect(_line2).Equals(_point6));
+
+      Assert.IsTrue(_line4.Intersect(_line5).Equals(_point5));
+      Assert.IsTrue(_line4.Intersect(_line5).Equals(_point5));
+    }    
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Plane3DTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Plane3DTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Plane3DTest.cs	(revision 15554)
@@ -0,0 +1,105 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.Geometry;
+using HeuristicLab.Problems.BinPacking3D;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Geometry.Test {
+  [TestClass]
+  public class Plane3DTest {
+
+    Line3D _line1;
+    Line3D _line2;
+    Line3D _line3;
+    Line3D _line4;
+    Line3D _line5;
+    Line3D _line6;
+
+    Vector3D _point1;
+    Vector3D _point2;
+    Vector3D _point3;
+    Vector3D _point4;
+    Vector3D _point5;
+    Vector3D _point6;
+
+    Plane3D _plane1;
+    Plane3D _plane2;
+    Plane3D _plane3;
+
+    [TestInitialize]
+    public void Initialize() {
+      _line1 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(10, 0, 0));
+      _line2 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(0, 10, 0));
+      _line3 = new Line3D(new Vector3D(0, 0, 0), new Vector3D(0, 0, 10));
+
+      _line4 = new Line3D(new Vector3D(-10, 2, 2), new Vector3D(10, 0, 0));
+      _line5 = new Line3D(new Vector3D(2, -10, 2), new Vector3D(0, 10, 0));
+      _line6 = new Line3D(new Vector3D(2, 2, -10), new Vector3D(0, 0, 10));
+
+      _point1 = new Vector3D(3, 0, 0);
+      _point2 = new Vector3D(0, 3, 0);
+      _point3 = new Vector3D(0, 0, 3);
+
+      _point4 = new Vector3D(5, 5, 5);
+      _point5 = new Vector3D(2, 2, 2);
+      _point6 = new Vector3D(0, 0, 0);
+
+      _plane1 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Top);
+      _plane2 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Right);
+      _plane3 = new Plane3D(_point6.ToPackingPosition(0), new PackingItem(10, 10, 10, new PackingShape()), Side.Front);
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIsElementOf() {
+      Assert.IsTrue(_plane1.IsElementOf(new Vector3D(0, 10, 0)));
+      Assert.IsTrue(_plane1.IsElementOf(new Vector3D(5, 10, 0)));
+      Assert.IsTrue(_plane1.IsElementOf(new Vector3D(0, 10, 5)));
+      Assert.IsTrue(_plane1.IsElementOf(new Vector3D(5, 10, 5)));
+      Assert.IsFalse(_plane1.IsElementOf(new Vector3D(0, 9, 0)));
+      Assert.IsFalse(_plane1.IsElementOf(new Vector3D(0, 11, 0)));
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersects() {
+      Assert.IsFalse(_plane1.Intersects(_line1));
+      Assert.IsTrue(_plane1.Intersects(_line2));
+      Assert.IsFalse(_plane1.Intersects(_line3));
+
+      Assert.IsTrue(_plane2.Intersects(_line1));
+      Assert.IsFalse(_plane2.Intersects(_line2));
+      Assert.IsFalse(_plane2.Intersects(_line3));
+
+      Assert.IsFalse(_plane3.Intersects(_line1));
+      Assert.IsFalse(_plane3.Intersects(_line2));
+      Assert.IsTrue(_plane3.Intersects(_line3));
+
+      Assert.IsTrue(_plane1.Intersects(new Line3D(new Vector3D(-1, -2, 2), new Vector3D(1, 3, 1))));
+      Assert.IsFalse(_plane1.Intersects(new Line3D(new Vector3D(-1, -2, 2), new Vector3D(-1, -3, 1))));
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIntersect() {
+      Assert.IsNull(_plane1.Intersect(_line1));
+      Assert.AreEqual(new Vector3D(0, 10, 0), _plane1.Intersect(_line2));
+      Assert.IsNull(_plane1.Intersect(_line3));
+
+      Assert.AreEqual(new Vector3D(10, 0, 0), _plane2.Intersect(_line1));
+      Assert.IsNull(_plane2.Intersect(_line2));
+      Assert.IsNull(_plane2.Intersect(_line3));
+
+      Assert.IsNull(_plane3.Intersect(_line1));
+      Assert.IsNull(_plane3.Intersect(_line2));
+      Assert.AreEqual(new Vector3D(0, 0, 10), _plane3.Intersect(_line3));
+      Assert.AreEqual(new Vector3D(3, 10, 6), _plane1.Intersect(new Line3D(new Vector3D(-1, -2, 2), new Vector3D(1, 3, 1))));
+      Assert.IsNull(_plane1.Intersect(new Line3D(new Vector3D(-1, -2, 2), new Vector3D(-1, -3, 1))));
+    }
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Vector3DTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Vector3DTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Geometry/Vector3DTest.cs	(revision 15554)
@@ -0,0 +1,206 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.Geometry;
+using HeuristicLab.Problems.BinPacking3D;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Geometry.Test {
+  [TestClass]
+  public class Vector3DTest {
+
+    Vector3D _point1;
+    Vector3D _point2;
+    Vector3D _point3;
+    Vector3D _point4;
+    Vector3D _point5;
+    Vector3D _point6;
+
+    PackingItem _item1;
+    PackingItem _item2;
+    PackingItem _item3;
+
+    [TestInitialize]
+    public void Initialize() {
+      _point1 = new Vector3D(3, 0, 0);
+      _point2 = new Vector3D(0, 3, 0);
+      _point3 = new Vector3D(0, 0, 3);
+
+      _point4 = new Vector3D(5, 5, 5);
+      _point5 = new Vector3D(2, 2, 2);
+      _point6 = new Vector3D(0, 0, 0);
+
+      _item1 = new PackingItem(10, 10, 10, new PackingShape());
+      _item2 = new PackingItem(20, 20, 20, new PackingShape());
+      _item3 = new PackingItem(30, 30, 30, new PackingShape());
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestAlongX() {
+      Assert.AreEqual(new Vector3D(13, 0, 0) ,Vector3D.AlongX(_point1.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(23, 0, 0), Vector3D.AlongX(_point1.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(33, 0, 0), Vector3D.AlongX(_point1.ToPackingPosition(0), _item3));
+
+
+      Assert.AreEqual(new Vector3D(10, 3, 0), Vector3D.AlongX(_point2.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(20, 3, 0), Vector3D.AlongX(_point2.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(30, 3, 0), Vector3D.AlongX(_point2.ToPackingPosition(0), _item3));
+
+      Assert.AreEqual(new Vector3D(10, 0, 3), Vector3D.AlongX(_point3.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(20, 0, 3), Vector3D.AlongX(_point3.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(30, 0, 3), Vector3D.AlongX(_point3.ToPackingPosition(0), _item3));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestAlongY() {
+      Assert.AreEqual(new Vector3D(3, 10, 0), Vector3D.AlongY(_point1.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(3, 20, 0), Vector3D.AlongY(_point1.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(3, 30, 0), Vector3D.AlongY(_point1.ToPackingPosition(0), _item3));
+
+
+      Assert.AreEqual(new Vector3D(0, 13, 0), Vector3D.AlongY(_point2.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(0, 23, 0), Vector3D.AlongY(_point2.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(0, 33, 0), Vector3D.AlongY(_point2.ToPackingPosition(0), _item3));
+
+      Assert.AreEqual(new Vector3D(0, 10, 3), Vector3D.AlongY(_point3.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(0, 20, 3), Vector3D.AlongY(_point3.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(0, 30, 3), Vector3D.AlongY(_point3.ToPackingPosition(0), _item3));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestAlongZ() {
+      Assert.AreEqual(new Vector3D(3, 0, 10), Vector3D.AlongZ(_point1.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(3, 0, 20), Vector3D.AlongZ(_point1.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(3, 0, 30), Vector3D.AlongZ(_point1.ToPackingPosition(0), _item3));
+
+
+      Assert.AreEqual(new Vector3D(0, 3, 10), Vector3D.AlongZ(_point2.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(0, 3, 20), Vector3D.AlongZ(_point2.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(0, 3, 30), Vector3D.AlongZ(_point2.ToPackingPosition(0), _item3));
+
+      Assert.AreEqual(new Vector3D(0, 0, 13), Vector3D.AlongZ(_point3.ToPackingPosition(0), _item1));
+      Assert.AreEqual(new Vector3D(0, 0, 23), Vector3D.AlongZ(_point3.ToPackingPosition(0), _item2));
+      Assert.AreEqual(new Vector3D(0, 0, 33), Vector3D.AlongZ(_point3.ToPackingPosition(0), _item3));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestCross() {
+      Assert.AreEqual(new Vector3D(0, 0, 9), _point1.Cross(_point2));
+      Assert.AreEqual(new Vector3D(0, 0, -9), _point2.Cross(_point1));
+      Assert.AreEqual(new Vector3D(9, 0, 0), _point2.Cross(_point3));
+      Assert.AreEqual(new Vector3D(-9, 0, 0), _point3.Cross(_point2));
+      Assert.AreEqual(new Vector3D(0, -9, 0), _point1.Cross(_point3));
+      Assert.AreEqual(new Vector3D(0, 9, 0), _point3.Cross(_point1));
+
+
+      Assert.AreEqual(new Vector3D(0, -15, 15), _point1.Cross(_point4));
+      Assert.AreEqual(new Vector3D(15, 0, -15), _point2.Cross(_point4));
+      Assert.AreEqual(new Vector3D(-15, 15, 0), _point3.Cross(_point4));
+
+      Assert.AreEqual(new Vector3D(0, 15, -15), _point4.Cross(_point1));
+      Assert.AreEqual(new Vector3D(-15, 0, 15), _point4.Cross(_point2));
+      Assert.AreEqual(new Vector3D(15, -15, 0), _point4.Cross(_point3));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestIsInside() {
+      Assert.IsFalse(_point1.IsInside(_point4.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsFalse(_point2.IsInside(_point4.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsFalse(_point3.IsInside(_point4.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+
+      Assert.IsTrue(_point1.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsTrue(_point2.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsTrue(_point3.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsTrue(_point6.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+
+      Assert.IsTrue(_point4.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsTrue(_point5.IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsTrue((new Vector3D(9, 9, 9)).IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsFalse((new Vector3D(11, 9, 9)).IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsFalse((new Vector3D(9, 11, 9)).IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+      Assert.IsFalse((new Vector3D(9, 9, 11)).IsInside(_point6.ToPackingPosition(0), ResidualSpace.Create(10, 10, 10)));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOperators() {
+      // static int operator *(Vector3D a, Vector3D b) 
+      Assert.AreEqual(0, (_point1 * _point2));
+      Assert.AreEqual(0, (_point2 * _point1));
+      Assert.AreEqual(0, (_point4 * _point6));
+      Assert.AreEqual(0, (_point6 * _point4));
+      Assert.AreEqual(15, (_point1 * _point4));
+      Assert.AreEqual(15, (_point4 * _point1));
+      Assert.AreEqual(30, (_point5 * _point4));
+      Assert.AreEqual(30, (_point4 * _point5));
+
+      // static Vector3D operator *(int a, Vector3D b), static Vector3D operator *(Vector3D a, int b)
+      Assert.AreEqual(new Vector3D(3, 0, 0), 1 * _point1);
+      Assert.AreEqual(new Vector3D(6, 0, 0), 2 * _point1);
+      Assert.AreEqual(new Vector3D(3, 0, 0), _point1 * 1);
+      Assert.AreEqual(new Vector3D(6, 0, 0), _point1 * 2);
+      Assert.AreEqual(2 * _point1, _point1 * 2);
+
+      Assert.AreEqual(new Vector3D(9, 0, 0), _point1 * 3);
+      Assert.AreEqual(new Vector3D(0, 9, 0), _point2 * 3);
+      Assert.AreEqual(new Vector3D(0, 0, 9), _point3 * 3);
+
+      Assert.AreEqual(new Vector3D(20, 20, 20), 4 * _point4);
+      Assert.AreEqual(new Vector3D(20, 20, 20), _point4 * 4);      
+      Assert.AreEqual(4 * _point4, _point4 * 4);
+
+      // static Vector3D operator *(double a, Vector3D b), static Vector3D operator *(Vector3D a, double b)
+      Assert.AreEqual(new Vector3D(3, 0, 0), 1.1 * _point1);
+      Assert.AreEqual(new Vector3D(6, 0, 0), 2.2 * _point1);
+      Assert.AreEqual(new Vector3D(3, 0, 0), _point1 * 1.1);
+      Assert.AreEqual(new Vector3D(6, 0, 0), _point1 * 2.2);
+      Assert.AreEqual(2.2 * _point1, _point1 * 2.2);
+      
+      Assert.AreEqual(new Vector3D(9, 0, 0), _point1 * 3.3);
+      Assert.AreEqual(new Vector3D(0, 9, 0), _point2 * 3.3);
+      Assert.AreEqual(new Vector3D(0, 0, 9), _point3 * 3.3);
+
+      Assert.AreEqual(new Vector3D(22, 22, 22), 4.4 * _point4);
+      Assert.AreEqual(new Vector3D(22, 22, 22), _point4 * 4.4);
+      Assert.AreEqual(4.4 * _point4, _point4 * 4.4);
+
+      // static Vector3D operator +(Vector3D a, Vector3D b)
+      Assert.AreEqual(new Vector3D(8, 5, 5), _point1 + _point4);
+      Assert.AreEqual(new Vector3D(5, 8, 5), _point2 + _point4);
+      Assert.AreEqual(new Vector3D(5, 5, 8), _point3 + _point4);
+      Assert.AreEqual(new Vector3D(7, 7, 7), _point4 + _point5);
+      Assert.AreEqual(_point4, _point4 + _point6);
+
+      // static Vector3D operator -(Vector3D a, Vector3D b)
+      Assert.AreEqual(new Vector3D(-2, -5, -5), _point1 - _point4);
+      Assert.AreEqual(new Vector3D(-5, -2, -5), _point2 - _point4);
+      Assert.AreEqual(new Vector3D(-5, -5, -2), _point3 - _point4);
+      Assert.AreEqual(new Vector3D(3, 3, 3), _point4 - _point5);
+      Assert.AreEqual(_point4, _point4 - _point6);
+
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestEquals() {
+      Assert.IsFalse(_point1.Equals(_point2));
+      Assert.IsFalse(_point1.Equals(new Vector3D(3, 0, 1)));
+      Assert.IsFalse(_point1.Equals(new Vector3D(3, 1, 0)));
+      Assert.IsFalse(_point1.Equals(new Vector3D(2, 0, 0)));
+
+      Assert.IsTrue(_point1.Equals(_point1));
+      Assert.IsTrue(_point5.Equals(new Vector3D(2, 2, 2)));
+    }
+    
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/RandomInstanceProviderTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/RandomInstanceProviderTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/RandomInstanceProviderTest.cs	(revision 15554)
@@ -0,0 +1,286 @@
+﻿using System;
+using System.IO;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D;
+using HeuristicLab.Problems.BinPacking3D.Instances;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Instances.Tests {
+  [TestClass]
+  public class RandomInstanceProviderTest {
+
+    private struct Dimension {
+      public int Id { get; set; }
+      public int Width { get; set; }
+      public int Height { get; set; }
+      public int Depth { get; set; }
+    }
+
+    #region TestRandomInstanceProvider
+
+
+    /// <summary>
+    /// Tests if the generated random instance equals to the references generated by david pisinger 
+    /// http://www.diku.dk/~pisinger/new3dbpp/test3dbpp.c
+    /// </summary>
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestRandomInstanceProvider() {
+
+      var referenceItemLists = ReadReferenceItemLists();
+      TestRandomInstanceProviderByClass(new RandomInstanceClass1Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass2Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass3Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass4Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass5Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass6Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass7Provider(), referenceItemLists);
+      TestRandomInstanceProviderByClass(new RandomInstanceClass8Provider(), referenceItemLists);
+
+    }
+
+    private IDictionary<string, List<Dimension>> ReadReferenceItemLists() {
+      var itemList = new Dictionary<string, List<Dimension>>();
+      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\ReferenceInstances";
+
+      string[] files = Directory.GetFiles(path);
+      foreach (string filePath in files) {
+        string key = Path.GetFileNameWithoutExtension(filePath);
+
+        using (StreamReader reader = new StreamReader(filePath)) {
+          int lineNumber = 1;
+          List<Dimension> dimensionList = new List<Dimension>();
+          while (!reader.EndOfStream) {
+            string line = reader.ReadLine();
+            if (lineNumber > 2) {
+              string[] lineValues = line.Split('\t');
+              int id;
+              int depth;
+              int width;
+              int height;
+              Int32.TryParse(lineValues[0], out id);
+              Int32.TryParse(lineValues[1], out depth);
+              Int32.TryParse(lineValues[2], out width);
+              Int32.TryParse(lineValues[3], out height);
+              dimensionList.Add(new Dimension() {
+                Id = id,
+                Depth = depth,
+                Width = width,
+                Height = height
+              });
+            }
+            lineNumber++;
+          }
+          itemList.Add(key, dimensionList);
+        }
+      }
+      return itemList;
+    }
+
+    private void TestRandomInstanceProviderByClass(RandomInstanceProvider randomInstanceProvider, IDictionary<string, List<Dimension>> referenceItems) {
+
+      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
+      foreach (var dataDescriptor in dataDescriptors) {
+        List<Dimension> testItemDimensions = null;
+        if (referenceItems.TryGetValue(dataDescriptor.Name, out testItemDimensions)) {
+          var packingItems = randomInstanceProvider.LoadData(dataDescriptor).Items;
+          Assert.IsNotNull(packingItems);
+          Assert.AreEqual(testItemDimensions.Count, packingItems.Length);
+          for (int i = 0; i < packingItems.Length; i++) {
+            Assert.AreEqual(testItemDimensions[i].Width, packingItems[i].Width);
+            Assert.AreEqual(testItemDimensions[i].Height, packingItems[i].Height);
+            Assert.AreEqual(testItemDimensions[i].Depth, packingItems[i].Depth);
+          }
+        }
+      }
+    }
+    #endregion
+
+    #region TestExtremePointAlgorithm
+
+    /// <summary>
+    /// Constants for testing the algorithm
+    /// The test parameters are defined in the paper 
+    /// </summary>
+    private const int NUMBER_OF_TEST_INSTANCES = 10;
+    private static readonly int[] TEST_CLASSES = { 1, 2 };
+    private static readonly int[] NUMBER_OF_TEST_ITEMS = { 50, 100, 150, 200 };
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass1() {
+      TestExtremePointAlgorithm(new RandomInstanceClass1Provider(), 1);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass2() {
+      TestExtremePointAlgorithm(new RandomInstanceClass2Provider(), 2);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass3() {
+      TestExtremePointAlgorithm(new RandomInstanceClass3Provider(), 3);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass4() {
+      TestExtremePointAlgorithm(new RandomInstanceClass4Provider(), 4);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass5() {
+      TestExtremePointAlgorithm(new RandomInstanceClass5Provider(), 5);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass6() {
+      TestExtremePointAlgorithm(new RandomInstanceClass6Provider(), 6);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass7() {
+      TestExtremePointAlgorithm(new RandomInstanceClass7Provider(), 7);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "long")]
+    public void TestExtremePointAlgorithmClass8() {
+      TestExtremePointAlgorithm(new RandomInstanceClass8Provider(), 8);
+    }
+
+    private void TestExtremePointAlgorithm(RandomInstanceProvider randomInstanceProvider, int @class) {
+      foreach (SortingMethod sortingMethod in Enum.GetValues(typeof(SortingMethod))) {
+        //foreach (FittingMethod fittingMethod in Enum.GetValues(typeof(FittingMethod))) {
+        FittingMethod fittingMethod = FittingMethod.FirstFit;
+        TestExtremePointAlgorithmByParameters(randomInstanceProvider, @class, sortingMethod, fittingMethod);
+        //}
+      }
+    }
+
+    private void TestExtremePointAlgorithmByParameters(RandomInstanceProvider randomInstanceProvider, int @class, SortingMethod sortingMethod, FittingMethod fittingMethod) {
+      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
+      var referenceValues = GetReferenceAlgorithmValues();
+      foreach (var numItems in NUMBER_OF_TEST_ITEMS) {
+        int sumNumberOfBins = 0;
+        for (int instance = 1; instance <= NUMBER_OF_TEST_INSTANCES; instance++) {
+          string name = string.Format("n={0}-id={1:00} (class={2})", numItems, instance, @class);
+          var selectedDataDescriptor = dataDescriptors.Where(dataDescriptor => dataDescriptor.Name == name);
+          Assert.IsNotNull(selectedDataDescriptor?.First());
+          var packingData = randomInstanceProvider.LoadData(selectedDataDescriptor.First());
+
+          ExtremePointAlgorithm algorithm = new ExtremePointAlgorithm();
+          algorithm.SortingMethodParameter.Value.Value = sortingMethod;
+          algorithm.FittingMethodParameter.Value.Value = fittingMethod;
+          algorithm.Problem.Load(packingData);
+
+          algorithm.Start();
+
+          PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem> bestPackingPlan = null;
+          foreach (Optimization.IResult result in algorithm.Results) {
+            if (result.Name == "Best Solution") {
+              bestPackingPlan = (PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem>)result.Value;
+              break;
+            }
+          }
+
+          sumNumberOfBins += bestPackingPlan.NrOfBins;
+        }
+
+        double referenceValue = 0.0;
+
+        if (referenceValues.TryGetValue(new Tuple<int, int, SortingMethod>(@class, numItems, sortingMethod), out referenceValue)) {
+          Console.WriteLine($"{numItems}-{@class}-{sortingMethod}: \tReference: {referenceValue} \tImplementation: {(double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES} \t{(referenceValue - ((double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES)):F2}");
+          Assert.AreEqual(referenceValue, (double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES, 20.0);
+        }
+      }
+    }
+
+
+    /// <summary>
+    /// Returns a dictionary which contains the reference values from table 2 given by the paper https://www.cirrelt.ca/DocumentsTravail/CIRRELT-2007-41.pdf 
+    /// Dictionary<Tuple<int, int, SortingMethod>, double> -> Dictionary<Tuple<@class, number of items, SortingMethod>, value>
+    /// </summary>
+    /// <returns></returns>
+    private Dictionary<Tuple<int, int, SortingMethod>, double> GetReferenceAlgorithmValues() {
+      Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues = new Dictionary<Tuple<int, int, SortingMethod>, double>();
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.Given, new double[] { 14.6, 29.2, 40.1, 55.9});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightVolume, new double[] { 15, 29.2, 39.9, 55.6 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.VolumeHeight, new double[] { 14.4, 29.5, 40.3, 55.7 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.AreaHeight, new double[] { 14.4, 28.3, 39.2, 53.2 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightArea, new double[] { 15, 29, 39.8, 55.1});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.ClusteredAreaHeight, new double[] { 14, 27.9, 38.1, 53 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.ClusteredHeightArea, new double[] { 13.8, 27.4, 37.7, 52.3 });
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.Given, new double[] { 29.7, 60.2, 88.5, 119.9 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightVolume, new double[] { 30.1, 59.6, 88.3, 120.1 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.VolumeHeight, new double[] { 29.9, 60.4, 88.6, 119.6 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.AreaHeight, new double[] { 30, 59.7, 88.4, 120.3 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightArea, new double[] { 30, 59.6, 88.3, 120 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.ClusteredAreaHeight, new double[] { 29.5, 59, 86.9, 119 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.ClusteredHeightArea, new double[] { 29.5, 59, 86.9, 118.9 });
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.Given, new double[] { 10.1, 18.1, 24.4, 32.5 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightVolume, new double[] { 9, 16.7, 22.9, 30.7});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.VolumeHeight, new double[] { 10, 17.8, 24.5, 32.6 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.AreaHeight, new double[] { 9.2, 16.1, 21.9, 29.5 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightArea, new double[] { 9, 16.6, 22.6, 30.5 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.ClusteredAreaHeight, new double[] { 8.5, 15.7, 21, 28.5 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.ClusteredHeightArea, new double[] { 8.4, 15.4, 21.1, 28.2});
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.Given, new double[] { 11.7, 21.7, 33, 44.4});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightVolume, new double[] { 10.9, 21.2, 31.8, 41.5 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.VolumeHeight, new double[] { 11.7, 22, 34.2, 44 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.AreaHeight, new double[] { 10.6, 20.2, 30.8, 39.5});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightArea, new double[] { 10.9, 20.5, 31, 39.8 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.ClusteredAreaHeight, new double[] { 10.2, 19.6, 29.9, 38.6 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.ClusteredHeightArea, new double[] { 10.1, 19.8, 30.2, 38.8 });
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.Given, new double[] { 9.4, 15.9, 19.3, 30 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightVolume, new double[] { 8.2, 14.6, 19.2, 28.1 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.VolumeHeight, new double[] { 9.3, 15.6, 19.7, 30.2 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.AreaHeight, new double[] { 8.1, 14.1, 18.2, 26.2 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightArea, new double[] { 8.1, 14.1, 18.9, 27,2 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.ClusteredAreaHeight, new double[] { 7.6, 13.4, 16.9, 25 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.ClusteredHeightArea, new double[] { 7.7, 13.3, 16.9, 24.9 });
+
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.Given, new double[] { 11.6, 22, 28.5, 35.4 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightVolume, new double[] { 10.5, 20.9, 27.4, 33.9 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.VolumeHeight, new double[] { 11.6, 22.1, 28.4, 35.4});
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.AreaHeight, new double[] { 10.1, 20.3, 26.4, 32.2 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightArea, new double[] { 10.5, 20.8, 37.7, 33.9 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.ClusteredAreaHeight, new double[] { 9.6, 19.4, 25.4, 31.4 });
+      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.ClusteredHeightArea, new double[] { 9.5, 19.7, 25.5, 31.5 });
+
+      return referenceValues;
+    }
+
+    private void AddToReferenceAlgorithmValuesDict(Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues, int @class, SortingMethod sortingMethod, double[] values) {
+      for (int i = 0; i < values.Length; i++) {
+        referenceValues.Add(new Tuple<int, int, SortingMethod>(@class, 50 + (50 * i), sortingMethod), values[i]);
+      }
+      
+    }
+
+
+    #endregion
+  }
+
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/ThreeDInstanceParserTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/ThreeDInstanceParserTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Instances/ThreeDInstanceParserTest.cs	(revision 15554)
@@ -0,0 +1,101 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using System.IO;
+using HeuristicLab.Problems.BinPacking3D.Instances;
+using System.Collections.Generic;
+using HeuristicLab.Problems.BinPacking3D;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Instances.Tests {
+  [TestClass]
+  public class ThreeDInstanceParserTest {
+    private PackingShape _packingShape;
+    private IList<PackingItem> _items1;
+    private IList<PackingItem> _items2;
+
+    [TestInitialize]
+    public void Initializes() {
+      _packingShape = new PackingShape(22, 23, 21);
+      _items1 = new List<PackingItem>();
+
+      _items1.Add(new PackingItem(8, 10, 10, _packingShape, 800, 1)); // 0,  V = 800,  A =  80, h = 10
+      _items1.Add(new PackingItem(10, 8, 10, _packingShape, 800, 2)); // 1,  V = 800,  A = 100, h =  8
+      _items1.Add(new PackingItem(10, 10, 8, _packingShape, 800, 3)); // 2,  V = 800,  A =  80, h = 10
+      _items1.Add(new PackingItem(8, 8, 10,  _packingShape, 640, 4)); // 3,   V = 640,  A =  80, h =  8
+      _items1.Add(new PackingItem(10, 8, 8,  _packingShape, 640, 0)); // 4,   V = 640,  A =  80, h =  8
+      _items1.Add(new PackingItem(8, 10, 8,  _packingShape, 640, 1)); // 5,   V = 640,  A =  64, h = 10  
+      _items1.Add(new PackingItem(8, 8, 8,   _packingShape, 512, 2)); // 6,    V = 512,  A =  64, h =  8
+
+      _items1.Add(new PackingItem(10, 10, 10, _packingShape,1000,3)); // 7, V = 1000, A = 100, h = 10
+
+      _items1.Add(new PackingItem(9, 10, 10, _packingShape, 900, 4)); // 8,  V = 900,  A =  90, h = 10
+      _items1.Add(new PackingItem(10, 9, 10, _packingShape, 900, 0)); // 9,  V = 900,  A = 100, h =  9
+      _items1.Add(new PackingItem(10, 10, 9, _packingShape, 900, 1)); // 10, V = 900,  A =  90, h = 10
+      _items1.Add(new PackingItem(9, 9, 10,  _packingShape, 810, 2)); // 11,  V = 810,  A =  90, h =  9
+      _items1.Add(new PackingItem(10, 9, 9,  _packingShape, 810, 3)); // 12,  V = 810,  A =  90, h =  9
+      _items1.Add(new PackingItem(9, 10, 9,  _packingShape, 810, 4)); // 13,  V = 810,  A =  81, h = 10
+      _items1.Add(new PackingItem(9, 9, 9,   _packingShape, 729, 0)); // 14,   V = 729,  A =  81, h =  9
+
+      _items2 = new List<PackingItem>();
+      _items2.Add(new PackingItem(8, 10, 10, _packingShape, 800, 1)); // 0,  V = 800,  A =  80, h = 10
+      _items2.Add(new PackingItem(10, 8, 10, _packingShape, 800, 2)); // 1,  V = 800,  A = 100, h =  8
+      _items2.Add(new PackingItem(10, 10, 8, _packingShape, 800, 3)); // 2,  V = 800,  A =  80, h = 10
+      _items2.Add(new PackingItem(8, 8, 10, _packingShape, 640, 4)); // 3,   V = 640,  A =  80, h =  8
+      _items2.Add(new PackingItem(10, 8, 8, _packingShape, 640, 0)); // 4,   V = 640,  A =  80, h =  8
+      _items2.Add(new PackingItem(8, 10, 8, _packingShape, 640, 1)); // 5,   V = 640,  A =  64, h = 10  
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestParse() {
+      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\Parser\3D-UnitTestParser1.txt";
+      ThreeDInstanceParser parser = new ThreeDInstanceParser();
+
+      using (var fileStream = File.Open(path, FileMode.Open)) {
+        parser.Parse(fileStream);
+      }
+      
+      Assert.AreEqual(_packingShape.Width, parser.Bin.Width);
+      Assert.AreEqual(_packingShape.Height, parser.Bin.Height);
+      Assert.AreEqual(_packingShape.Depth, parser.Bin.Depth);
+
+      Assert.AreEqual(_items1.Count, parser.Items.Count);
+      for (int i = 0; i < parser.Items.Count; i++) {
+        PackingItem expected = _items1[i];
+        PackingItem actual = parser.Items[i];
+        Assert.AreEqual(expected.Width, actual.Width);
+        Assert.AreEqual(expected.Height, actual.Height);
+        Assert.AreEqual(expected.Depth, actual.Depth);
+        Assert.AreEqual(expected.Material, actual.Material);
+        Assert.AreEqual(expected.Weight, actual.Weight);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestParseUncompleteFile() {
+      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\Parser\3D-UnitTestParser2.txt";
+      ThreeDInstanceParser parser = new ThreeDInstanceParser();
+
+      using (var fileStream = File.Open(path, FileMode.Open)) {
+        parser.Parse(fileStream);
+      }
+
+      Assert.AreEqual(_packingShape.Width, parser.Bin.Width);
+      Assert.AreEqual(_packingShape.Height, parser.Bin.Height);
+      Assert.AreEqual(_packingShape.Depth, parser.Bin.Depth);
+
+      Assert.AreEqual(_items2.Count, parser.Items.Count);
+      for (int i = 0; i < parser.Items.Count; i++) {
+        PackingItem expected = _items2[i];
+        PackingItem actual = parser.Items[i];
+        Assert.AreEqual(expected.Width, actual.Width);
+        Assert.AreEqual(expected.Height, actual.Height);
+        Assert.AreEqual(expected.Depth, actual.Depth);
+        Assert.AreEqual(expected.Material, actual.Material);
+        Assert.AreEqual(expected.Weight, actual.Weight);
+      }
+    }
+  }
+}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/PermutationSortingTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/PermutationSortingTest.cs	(revision 15553)
+++ 	(revision )
@@ -1,184 +1,0 @@
-﻿using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HeuristicLab.Problems.BinPacking3D;
-using System.Collections.Generic;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Problems.BinPacking3D.Sorting;
-
-namespace HeuristicLab.Problems.BinPacking._3D.Tests {
-  [TestClass]
-  public class PermutationSortingTest {
-    private PackingShape _packingShape;
-    private IList<PackingItem> _items;
-
-    [TestInitialize]
-    public void Initializes() {
-      _packingShape = new PackingShape(20, 20, 20);
-      _items = new List<PackingItem>();
-
-      _items.Add(new PackingItem(8, 10, 10, _packingShape, 1000, 1)); // 0,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(10, 8, 10, _packingShape, 1000, 2)); // 1,  V = 800,  A = 100, h =  8
-      _items.Add(new PackingItem(10, 10, 8, _packingShape, 1000, 3)); // 2,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(8, 8, 10, _packingShape, 1000, 4)); // 3,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(10, 8, 8, _packingShape, 1000, 0)); // 4,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(8, 10, 8, _packingShape, 1000, 1)); // 5,   V = 640,  A =  64, h = 10  
-      _items.Add(new PackingItem(8, 8, 8, _packingShape, 1000, 2)); // 6,    V = 512,  A =  64, h =  8
-
-      _items.Add(new PackingItem(10, 10, 10, _packingShape, 1000, 3)); // 7, V = 1000, A = 100, h = 10
-
-      _items.Add(new PackingItem(9, 10, 10, _packingShape, 1000, 4)); // 8,  V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(10, 9, 10, _packingShape, 1000, 0)); // 9,  V = 900,  A = 100, h =  9
-      _items.Add(new PackingItem(10, 10, 9, _packingShape, 1000, 1)); // 10, V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(9, 9, 10, _packingShape, 1000, 2)); // 11,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(10, 9, 9, _packingShape, 1000, 3)); // 12,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(9, 10, 9, _packingShape, 1000, 4)); // 13,  V = 810,  A =  81, h = 10
-      _items.Add(new PackingItem(9, 9, 9, _packingShape, 1000, 0)); // 14,   V = 729,  A =  81, h =  9
-    }
-
-    
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByVolumeHeightExtension() {
-      Permutation actual = _items.SortByVolumeHeight();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7,  8, 10, 9, 13, 11, 12, 0, 2, 1, 14, 5, 3, 4, 6});
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-    
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByHeightVolumeExtension() {
-      Permutation actual = _items.SortByHeightVolume();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 8, 10, 13, 0, 2, 5, 9, 11, 12, 14, 1, 3, 4, 6 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByAreaHeightExtension() {
-      Permutation actual = _items.SortByAreaHeight();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 9, 1, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6});
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-    
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByHeightAreaExtension() {
-      Permutation actual = _items.SortByHeightArea();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 8, 10, 13, 0, 2, 5, 9, 11, 12, 14, 1, 3, 4, 6});
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByClusteredAreaHeightExtension() {
-      Permutation actual = _items.SortByClusteredAreaHeight(_packingShape, 1.0);
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 0, 2, 5, 7, 8, 10, 13, 9, 11, 12, 14, 1, 3, 4, 6 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByClusteredHeightAreaExtension() {
-      Permutation actual = _items.SortByClusteredHeightArea(_packingShape, 1.0);
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 1, 7, 9, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialVolumeHeightExtension() {
-      Permutation actual = _items.SortByMaterialVolumeHeight();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 12, 2, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialHeightVolumeExtension() {
-      Permutation actual = _items.SortByMaterialHeightVolume();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 2, 12, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialAreaHeightExtension() {
-      Permutation actual = _items.SortByMaterialAreaHeight();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 12, 2, 1, 11, 6, 10, 0, 5, 9, 14, 4 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialHeightAreaExtension() {
-      Permutation actual = _items.SortByMaterialHeightArea();
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 2, 12, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialClusteredAreaHeightExtension() {
-      Permutation actual = _items.SortByMaterialClusteredAreaHeight(_packingShape, 1.0);
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 2, 7, 12, 11, 1, 6, 0, 5, 10, 9, 14, 4 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestSortByMaterialClusteredHeightAreaExtension() {
-      Permutation actual = _items.SortByClusteredHeightArea(_packingShape, 1.0);
-      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 1, 7, 9, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6 });
-      for (int i = 0; i < expected.Length; i++) {
-        Assert.AreEqual(expected[i], actual[i]);
-      }
-    }
-
-    
-    /*
-      _items.Add(new PackingItem(8, 10, 10, _packingShape, 1000, 1)); // 0,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(10, 8, 10, _packingShape, 1000, 2)); // 1,  V = 800,  A = 100, h =  8
-      _items.Add(new PackingItem(10, 10, 8, _packingShape, 1000, 3)); // 2,  V = 800,  A =  80, h = 10
-      _items.Add(new PackingItem(8, 8, 10, _packingShape, 1000, 4)); // 3,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(10, 8, 8, _packingShape, 1000, 0)); // 4,   V = 640,  A =  80, h =  8
-      _items.Add(new PackingItem(8, 10, 8, _packingShape, 1000, 1)); // 5,   V = 640,  A =  64, h = 10  
-      _items.Add(new PackingItem(8, 8, 8, _packingShape, 1000, 2)); // 6,    V = 512,  A =  64, h =  8
-
-      _items.Add(new PackingItem(10, 10, 10, _packingShape, 1000, 3)); // 7, V = 1000, A = 100, h = 10
-
-      _items.Add(new PackingItem(9, 10, 10, _packingShape, 1000, 4)); // 8,  V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(10, 9, 10, _packingShape, 1000, 0)); // 9,  V = 900,  A = 100, h =  9
-      _items.Add(new PackingItem(10, 10, 9, _packingShape, 1000, 1)); // 10, V = 900,  A =  90, h = 10
-      _items.Add(new PackingItem(9, 9, 10, _packingShape, 1000, 2)); // 11,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(10, 9, 9, _packingShape, 1000, 3)); // 12,  V = 810,  A =  90, h =  9
-      _items.Add(new PackingItem(9, 10, 9, _packingShape, 1000, 4)); // 13,  V = 810,  A =  81, h = 10
-      _items.Add(new PackingItem(9, 9, 9, _packingShape, 1000, 0)); // 14,   V = 729,  A =  81, h =  9
-      */
-  }
-}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/RandomInstanceProviderTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/RandomInstanceProviderTest.cs	(revision 15553)
+++ 	(revision )
@@ -1,277 +1,0 @@
-﻿using System;
-using System.IO;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using HeuristicLab.Problems.BinPacking3D;
-using HeuristicLab.Problems.BinPacking3D.Instances;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Core;
-
-namespace HeuristicLab.Problems.BinPacking._3D.Tests {
-  [TestClass]
-  public class RandomInstanceProviderTest {
-
-    private struct Dimension {
-      public int Id { get; set; }
-      public int Width { get; set; }
-      public int Height { get; set; }
-      public int Depth { get; set; }
-    }
-
-    #region TestRandomInstanceProvider
-
-
-    /// <summary>
-    /// Tests if the generated random instance equals to the references generated by david pisinger 
-    /// http://www.diku.dk/~pisinger/new3dbpp/test3dbpp.c
-    /// </summary>
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestRandomInstanceProvider() {
-
-      var referenceItemLists = ReadReferenceItemLists();
-      TestRandomInstanceProviderByClass(new RandomInstanceClass1Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass2Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass3Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass4Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass5Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass6Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass7Provider(), referenceItemLists);
-      TestRandomInstanceProviderByClass(new RandomInstanceClass8Provider(), referenceItemLists);
-
-    }
-
-    private IDictionary<string, List<Dimension>> ReadReferenceItemLists() {
-      var itemList = new Dictionary<string, List<Dimension>>();
-      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\ReferenceInstances";
-
-      string[] files = Directory.GetFiles(path);
-      foreach (string filePath in files) {
-        string key = Path.GetFileNameWithoutExtension(filePath);
-
-        using (StreamReader reader = new StreamReader(filePath)) {
-          int lineNumber = 1;
-          List<Dimension> dimensionList = new List<Dimension>();
-          while (!reader.EndOfStream) {
-            string line = reader.ReadLine();
-            if (lineNumber > 2) {
-              string[] lineValues = line.Split('\t');
-              int id;
-              int depth;
-              int width;
-              int height;
-              Int32.TryParse(lineValues[0], out id);
-              Int32.TryParse(lineValues[1], out depth);
-              Int32.TryParse(lineValues[2], out width);
-              Int32.TryParse(lineValues[3], out height);
-              dimensionList.Add(new Dimension() {
-                Id = id,
-                Depth = depth,
-                Width = width,
-                Height = height
-              });
-            }
-            lineNumber++;
-          }
-          itemList.Add(key, dimensionList);
-        }
-      }
-      return itemList;
-    }
-
-    private void TestRandomInstanceProviderByClass(RandomInstanceProvider randomInstanceProvider, IDictionary<string, List<Dimension>> referenceItems) {
-
-      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
-      foreach (var dataDescriptor in dataDescriptors) {
-        List<Dimension> testItemDimensions = null;
-        if (referenceItems.TryGetValue(dataDescriptor.Name, out testItemDimensions)) {
-          var packingItems = randomInstanceProvider.LoadData(dataDescriptor).Items;
-          Assert.IsNotNull(packingItems);
-          Assert.AreEqual(testItemDimensions.Count, packingItems.Length);
-          for (int i = 0; i < packingItems.Length; i++) {
-            Assert.AreEqual(testItemDimensions[i].Width, packingItems[i].Width);
-            Assert.AreEqual(testItemDimensions[i].Height, packingItems[i].Height);
-            Assert.AreEqual(testItemDimensions[i].Depth, packingItems[i].Depth);
-          }
-        }
-      }
-    }
-    #endregion
-
-    #region TestExtremePointAlgorithm
-
-    /// <summary>
-    /// Constants for testing the algorithm
-    /// The test parameters are defined in the paper 
-    /// </summary>
-    private const int NUMBER_OF_TEST_INSTANCES = 10;
-    private static readonly int[] TEST_CLASSES = { 1, 2 };
-    private static readonly int[] NUMBER_OF_TEST_ITEMS = { 50, 100, 150, 200 };
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass1() {
-      TestExtremePointAlgorithm(new RandomInstanceClass1Provider(), 1);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass2() {
-      TestExtremePointAlgorithm(new RandomInstanceClass2Provider(), 2);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass3() {
-      TestExtremePointAlgorithm(new RandomInstanceClass3Provider(), 3);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass4() {
-      TestExtremePointAlgorithm(new RandomInstanceClass4Provider(), 4);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass5() {
-      TestExtremePointAlgorithm(new RandomInstanceClass5Provider(), 5);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass6() {
-      TestExtremePointAlgorithm(new RandomInstanceClass6Provider(), 6);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass7() {
-      TestExtremePointAlgorithm(new RandomInstanceClass7Provider(), 7);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestExtremePointAlgorithmClass8() {
-      TestExtremePointAlgorithm(new RandomInstanceClass8Provider(), 8);
-    }
-
-    private void TestExtremePointAlgorithm(RandomInstanceProvider randomInstanceProvider, int @class) {
-      foreach (SortingMethod sortingMethod in Enum.GetValues(typeof(SortingMethod))) {
-        //foreach (FittingMethod fittingMethod in Enum.GetValues(typeof(FittingMethod))) {
-        FittingMethod fittingMethod = FittingMethod.FirstFit;
-        TestExtremePointAlgorithmByParameters(randomInstanceProvider, @class, sortingMethod, fittingMethod);
-        //}
-      }
-    }
-
-    private void TestExtremePointAlgorithmByParameters(RandomInstanceProvider randomInstanceProvider, int @class, SortingMethod sortingMethod, FittingMethod fittingMethod) {
-      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
-      var referenceValues = GetReferenceAlgorithmValues();
-      foreach (var numItems in NUMBER_OF_TEST_ITEMS) {
-        int sumNumberOfBins = 0;
-        for (int instance = 1; instance <= NUMBER_OF_TEST_INSTANCES; instance++) {
-          string name = string.Format("n={0}-id={1:00} (class={2})", numItems, instance, @class);
-          var selectedDataDescriptor = dataDescriptors.Where(dataDescriptor => dataDescriptor.Name == name);
-          Assert.IsNotNull(selectedDataDescriptor?.First());
-          var packingData = randomInstanceProvider.LoadData(selectedDataDescriptor.First());
-
-          ExtremePointAlgorithm algorithm = new ExtremePointAlgorithm();
-          algorithm.SortingMethodParameter.Value.Value = sortingMethod;
-          algorithm.FittingMethodParameter.Value.Value = fittingMethod;
-          algorithm.Problem.Load(packingData);
-
-          algorithm.Start();
-
-          PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem> bestPackingPlan = null;
-          foreach (Optimization.IResult result in algorithm.Results) {
-            if (result.Name == "Best Solution") {
-              bestPackingPlan = (PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem>)result.Value;
-              break;
-            }
-          }
-
-          sumNumberOfBins += bestPackingPlan.NrOfBins;
-        }
-
-        double referenceValue = 0.0;
-
-        if (referenceValues.TryGetValue(new Tuple<int, int, SortingMethod>(@class, numItems, sortingMethod), out referenceValue)) {
-          Console.WriteLine($"{numItems}-{@class}-{sortingMethod}: \tReference: {referenceValue} \tImplementation: {(double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES} \t{(referenceValue - ((double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES)):F2}");
-          Assert.AreEqual(referenceValue, (double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES, 20.0);
-        }
-      }
-    }
-
-
-    /// <summary>
-    /// Returns a dictionary which contains the reference values from table 2 given by the paper https://www.cirrelt.ca/DocumentsTravail/CIRRELT-2007-41.pdf 
-    /// Dictionary<Tuple<int, int, SortingMethod>, double> -> Dictionary<Tuple<@class, number of items, SortingMethod>, value>
-    /// </summary>
-    /// <returns></returns>
-    private Dictionary<Tuple<int, int, SortingMethod>, double> GetReferenceAlgorithmValues() {
-      Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues = new Dictionary<Tuple<int, int, SortingMethod>, double>();
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.Given, new double[] { 14.6, 29.2, 40.1, 55.9});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightVolume, new double[] { 15, 29.2, 39.9, 55.6 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.VolumeHeight, new double[] { 14.4, 29.5, 40.3, 55.7 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.AreaHeight, new double[] { 14.4, 28.3, 39.2, 53.2 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightArea, new double[] { 15, 29, 39.8, 55.1});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.ClusteredAreaHeight, new double[] { 14, 27.9, 38.1, 53 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.ClusteredHeightArea, new double[] { 13.8, 27.4, 37.7, 52.3 });
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.Given, new double[] { 29.7, 60.2, 88.5, 119.9 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightVolume, new double[] { 30.1, 59.6, 88.3, 120.1 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.VolumeHeight, new double[] { 29.9, 60.4, 88.6, 119.6 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.AreaHeight, new double[] { 30, 59.7, 88.4, 120.3 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightArea, new double[] { 30, 59.6, 88.3, 120 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.ClusteredAreaHeight, new double[] { 29.5, 59, 86.9, 119 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.ClusteredHeightArea, new double[] { 29.5, 59, 86.9, 118.9 });
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.Given, new double[] { 10.1, 18.1, 24.4, 32.5 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightVolume, new double[] { 9, 16.7, 22.9, 30.7});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.VolumeHeight, new double[] { 10, 17.8, 24.5, 32.6 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.AreaHeight, new double[] { 9.2, 16.1, 21.9, 29.5 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightArea, new double[] { 9, 16.6, 22.6, 30.5 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.ClusteredAreaHeight, new double[] { 8.5, 15.7, 21, 28.5 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.ClusteredHeightArea, new double[] { 8.4, 15.4, 21.1, 28.2});
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.Given, new double[] { 11.7, 21.7, 33, 44.4});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightVolume, new double[] { 10.9, 21.2, 31.8, 41.5 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.VolumeHeight, new double[] { 11.7, 22, 34.2, 44 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.AreaHeight, new double[] { 10.6, 20.2, 30.8, 39.5});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightArea, new double[] { 10.9, 20.5, 31, 39.8 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.ClusteredAreaHeight, new double[] { 10.2, 19.6, 29.9, 38.6 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.ClusteredHeightArea, new double[] { 10.1, 19.8, 30.2, 38.8 });
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.Given, new double[] { 9.4, 15.9, 19.3, 30 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightVolume, new double[] { 8.2, 14.6, 19.2, 28.1 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.VolumeHeight, new double[] { 9.3, 15.6, 19.7, 30.2 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.AreaHeight, new double[] { 8.1, 14.1, 18.2, 26.2 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightArea, new double[] { 8.1, 14.1, 18.9, 27,2 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.ClusteredAreaHeight, new double[] { 7.6, 13.4, 16.9, 25 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.ClusteredHeightArea, new double[] { 7.7, 13.3, 16.9, 24.9 });
-
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.Given, new double[] { 11.6, 22, 28.5, 35.4 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightVolume, new double[] { 10.5, 20.9, 27.4, 33.9 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.VolumeHeight, new double[] { 11.6, 22.1, 28.4, 35.4});
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.AreaHeight, new double[] { 10.1, 20.3, 26.4, 32.2 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightArea, new double[] { 10.5, 20.8, 37.7, 33.9 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.ClusteredAreaHeight, new double[] { 9.6, 19.4, 25.4, 31.4 });
-      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.ClusteredHeightArea, new double[] { 9.5, 19.7, 25.5, 31.5 });
-
-      return referenceValues;
-    }
-
-    private void AddToReferenceAlgorithmValuesDict(Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues, int @class, SortingMethod sortingMethod, double[] values) {
-      for (int i = 0; i < values.Length; i++) {
-        referenceValues.Add(new Tuple<int, int, SortingMethod>(@class, 50 + (50 * i), sortingMethod), values[i]);
-      }
-      
-    }
-
-
-    #endregion
-  }
-
-}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculatorTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculatorTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ResidualSpaceCalculation/ResidualSpaceCalculatorTest.cs	(revision 15554)
@@ -0,0 +1,319 @@
+﻿using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D.Geometry;
+using HeuristicLab.Problems.BinPacking3D.ResidualSpaceCalculation;
+using HeuristicLab.Problems.BinPacking._3D.Utils.Tests;
+using HeuristicLab.Problems.BinPacking3D;
+
+namespace HeuristicLab.Problems.BinPacking._3D.ResidualSpaceCalculation.Tests {
+  /// <summary>
+  /// Summary description for ResidualSpaceCalculator
+  /// </summary>
+  [TestClass]
+  public class ResidualSpaceCalculatorTest {
+
+    #region Points, residual spaces, packing positions and items
+
+    Vector3D _point1;
+    Vector3D _point2;
+    Vector3D _point3;
+    Vector3D _point4;
+    Vector3D _point5;
+    Vector3D _point6;
+    Vector3D _point7;
+    Vector3D _point8;
+    Vector3D _point9;
+    Vector3D _point10;
+    Vector3D _point11;
+
+    ResidualSpace _rs1;
+    ResidualSpace _rs2;
+    ResidualSpace _rs3;
+    ResidualSpace _rs4;
+    ResidualSpace _rs5;
+    ResidualSpace _rs6;
+    ResidualSpace _rs7;
+
+    BinPacking3D.PackingPosition _pos1;
+    BinPacking3D.PackingPosition _pos2;
+    BinPacking3D.PackingPosition _pos3;
+    BinPacking3D.PackingPosition _pos4;
+    BinPacking3D.PackingPosition _pos5;
+    BinPacking3D.PackingPosition _pos6;
+    BinPacking3D.PackingPosition _pos7;
+    BinPacking3D.PackingPosition _pos8;
+    BinPacking3D.PackingPosition _pos9;
+    BinPacking3D.PackingPosition _pos10;
+    BinPacking3D.PackingPosition _pos11;
+
+    BinPacking3D.PackingItem _item1;
+    BinPacking3D.PackingItem _item2;
+    BinPacking3D.PackingItem _item3;
+    BinPacking3D.PackingItem _item4;
+    BinPacking3D.PackingItem _item5;
+    BinPacking3D.PackingItem _item6;
+    BinPacking3D.PackingItem _item7;
+
+    BinPacking3D.BinPacking3D _bp1;
+    BinPacking3D.BinPacking3D _bp2;
+    BinPacking3D.BinPacking3D _bp3;
+    #endregion
+
+    IResidualSpaceCalculator _calculator;
+
+    [TestInitialize]
+    public void Initialize() {
+      _calculator = ResidualSpaceCalculatorFactory.CreateCalculator();
+      _point1 = new Vector3D(0, 0, 0);
+      _point2 = new Vector3D(0, 10, 10);
+      _point3 = new Vector3D(10, 0, 10);
+      _point4 = new Vector3D(10, 10, 0);
+
+      _point5 = new Vector3D(10, 20, 20);
+      _point6 = new Vector3D(20, 10, 20);
+      _point7 = new Vector3D(20, 20, 10);
+
+      _point8 = new Vector3D(0, 20, 20);
+      _point9 = new Vector3D(20, 0, 20);
+      _point10 = new Vector3D(20, 20, 0);
+      _point11 = new Vector3D(20, 20, 20);
+
+      _rs1 = new ResidualSpace(5, 5, 5);
+      _rs2 = new ResidualSpace(10, 10, 10);
+      _rs3 = new ResidualSpace(20, 20, 20);
+      _rs4 = new ResidualSpace(30, 30, 30);
+      _rs5 = new ResidualSpace(10, 20, 20);
+      _rs6 = new ResidualSpace(20, 10, 20);
+      _rs7 = new ResidualSpace(20, 20, 10);
+
+      _pos1 = _point1.ToPackingPosition(0);
+      _pos2 = _point2.ToPackingPosition(0);
+      _pos3 = _point3.ToPackingPosition(0);
+      _pos4 = _point4.ToPackingPosition(0);
+      _pos5 = _point5.ToPackingPosition(0);
+      _pos6 = _point6.ToPackingPosition(0);
+      _pos7 = _point7.ToPackingPosition(0);
+      _pos8 = _point8.ToPackingPosition(0);
+      _pos9 = _point9.ToPackingPosition(0);
+      _pos10 = _point10.ToPackingPosition(0);
+      _pos11 = _point11.ToPackingPosition(0);
+
+      _item1 = _rs1.ToPackingItem();
+      _item2 = _rs2.ToPackingItem();
+      _item3 = _rs3.ToPackingItem();
+      _item4 = _rs4.ToPackingItem();
+      _item5 = _rs5.ToPackingItem();
+      _item6 = _rs6.ToPackingItem();
+      _item7 = _rs7.ToPackingItem();
+
+      _bp1 = new BinPacking3D.BinPacking3D(new PackingShape(30, 30, 30));
+      _bp1.PackItem(0, _item4, _pos2);
+      _bp2 = new BinPacking3D.BinPacking3D(new PackingShape(30, 30, 30));
+      _bp2.PackItem(0, _item4, _pos5);
+      _bp3 = new BinPacking3D.BinPacking3D(new PackingShape(30, 30, 30));
+      _bp3.PackItem(0, _item4, _pos4);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsX() {      
+      Assert.IsFalse( (bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point1, _rs1, _pos3, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point3, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point3, _rs1, _pos6, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point1, _rs3, _pos3, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point3, _rs3, _pos1, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point1, _rs3, _pos1, _item2 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsX", new object[] { _point1, _rs2, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsY() {
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point1, _rs1, _pos2, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point2, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point2, _rs1, _pos5, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point1, _rs3, _pos2, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point2, _rs3, _pos1, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point1, _rs3, _pos1, _item2 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsY", new object[] { _point1, _rs2, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsZ() {
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point1, _rs1, _pos2, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point2, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point2, _rs1, _pos5, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point1, _rs3, _pos2, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point2, _rs3, _pos1, _item3 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point1, _rs3, _pos1, _item2 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsZ", new object[] { _point1, _rs2, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsOnRight() {
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs1, _pos9, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs1, _pos10, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs1, _pos11, _item1 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point9, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point10, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point11, _rs1, _pos1, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs4, _pos9, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs4, _pos10, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs4, _pos11, _item4 }));
+      
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs3, _pos9, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs3, _pos10, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point1, _rs3, _pos11, _item3 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point9, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point10, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsOnRight", new object[] { _point11, _rs3, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsInFront() {
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs1, _pos9, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs1, _pos8, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs1, _pos11, _item1 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point9, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point8, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point11, _rs1, _pos1, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs4, _pos9, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs4, _pos8, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs4, _pos11, _item4 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs3, _pos9, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs3, _pos8, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point1, _rs3, _pos11, _item3 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point9, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point8, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsInFront", new object[] { _point11, _rs3, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestOverlapsAbove() {
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs1, _pos8, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs1, _pos10, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs1, _pos11, _item1 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point8, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point10, _rs1, _pos1, _item1 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point11, _rs1, _pos1, _item1 }));
+
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs4, _pos8, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs4, _pos10, _item4 }));
+      Assert.IsTrue((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs4, _pos11, _item4 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs3, _pos8, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs3, _pos10, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point1, _rs3, _pos11, _item3 }));
+
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point8, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point10, _rs3, _pos1, _item3 }));
+      Assert.IsFalse((bool)TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "OverlapsAbove", new object[] { _point11, _rs3, _pos1, _item3 }));
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestLimitResidualSpaceOnRight() {
+
+      ResidualSpace rs1 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs2 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs3 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs4 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs5 = _rs4.Clone() as ResidualSpace;
+      rs4.Height = 20;
+      rs5.Height = 10;
+
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceOnRight", new object[] { _bp1, _point1, rs1 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceOnRight", new object[] { _bp2, _point1, rs2 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceOnRight", new object[] { _bp3, _point1, rs3 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceOnRight", new object[] { _bp2, _point1, rs4 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceOnRight", new object[] { _bp3, _point1, rs5 });
+      Assert.AreEqual(30, rs1.Width);
+      Assert.AreEqual(10, rs2.Width);
+      Assert.AreEqual(10, rs3.Width);
+      Assert.AreEqual(30, rs4.Width);
+      Assert.AreEqual(30, rs5.Width);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestLimitResidualSpaceInFront() {
+      ResidualSpace rs1 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs2 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs3 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs4 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs5 = _rs4.Clone() as ResidualSpace;
+      rs4.Height = 20;
+      rs5.Height = 10;
+
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceInFront", new object[] { _bp1, _point1, rs1 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceInFront", new object[] { _bp2, _point1, rs2 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceInFront", new object[] { _bp3, _point1, rs3 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceInFront", new object[] { _bp2, _point1, rs4 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceInFront", new object[] { _bp1, _point1, rs5 });
+      Assert.AreEqual(10, rs1.Depth);
+      Assert.AreEqual(20, rs2.Depth);
+      Assert.AreEqual(30, rs3.Depth);
+      Assert.AreEqual(30, rs4.Depth);
+      Assert.AreEqual(30, rs5.Depth);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestLimitResidualSpaceAbove() {
+      ResidualSpace rs1 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs2 = _rs4.Clone() as ResidualSpace;
+      ResidualSpace rs3 = _rs4.Clone() as ResidualSpace;
+
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceAbove", new object[] { _bp1, _point1, rs1 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceAbove", new object[] { _bp2, _point1, rs2 });
+      TestUtils.InvokeMethod(_calculator.GetType(), _calculator, "LimitResidualSpaceAbove", new object[] { _bp3, _point1, rs3 });
+      Assert.AreEqual(10, rs1.Height);
+      Assert.AreEqual(20, rs2.Height);
+      Assert.AreEqual(10, rs3.Height);
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestCalculateResidualSpaces() {
+      var residualSpaces = _calculator.CalculateResidualSpaces(_bp2, _point1).ToList();
+      Assert.AreEqual(3, residualSpaces.Count);
+      Assert.AreEqual(10, residualSpaces[0].Width);
+      Assert.AreEqual(30, residualSpaces[0].Height);
+      Assert.AreEqual(30, residualSpaces[0].Depth);
+      Assert.AreEqual(30, residualSpaces[1].Width);
+      Assert.AreEqual(30, residualSpaces[1].Height);
+      Assert.AreEqual(20, residualSpaces[1].Depth);
+      Assert.AreEqual(30, residualSpaces[2].Width);
+      Assert.AreEqual(20, residualSpaces[2].Height);
+      Assert.AreEqual(30, residualSpaces[2].Depth);
+    }
+  }
+}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Sorting/PermutationSortingTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Sorting/PermutationSortingTest.cs	(revision 15554)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/Sorting/PermutationSortingTest.cs	(revision 15554)
@@ -0,0 +1,175 @@
+﻿using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.Problems.BinPacking3D;
+using System.Collections.Generic;
+using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Problems.BinPacking3D.Sorting;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Sorting.Tests {
+  [TestClass]
+  public class PermutationSortingTest {
+    private PackingShape _packingShape;
+    private IList<PackingItem> _items;
+
+    [TestInitialize]
+    public void Initializes() {
+      _packingShape = new PackingShape(20, 20, 20);
+      _items = new List<PackingItem>();
+
+      _items.Add(new PackingItem(8, 10, 10, _packingShape, 1000, 1)); // 0,  V = 800,  A =  80, h = 10
+      _items.Add(new PackingItem(10, 8, 10, _packingShape, 1000, 2)); // 1,  V = 800,  A = 100, h =  8
+      _items.Add(new PackingItem(10, 10, 8, _packingShape, 1000, 3)); // 2,  V = 800,  A =  80, h = 10
+      _items.Add(new PackingItem(8, 8, 10, _packingShape, 1000, 4)); // 3,   V = 640,  A =  80, h =  8
+      _items.Add(new PackingItem(10, 8, 8, _packingShape, 1000, 0)); // 4,   V = 640,  A =  80, h =  8
+      _items.Add(new PackingItem(8, 10, 8, _packingShape, 1000, 1)); // 5,   V = 640,  A =  64, h = 10  
+      _items.Add(new PackingItem(8, 8, 8, _packingShape, 1000, 2)); // 6,    V = 512,  A =  64, h =  8
+
+      _items.Add(new PackingItem(10, 10, 10, _packingShape, 1000, 3)); // 7, V = 1000, A = 100, h = 10
+
+      _items.Add(new PackingItem(9, 10, 10, _packingShape, 1000, 4)); // 8,  V = 900,  A =  90, h = 10
+      _items.Add(new PackingItem(10, 9, 10, _packingShape, 1000, 0)); // 9,  V = 900,  A = 100, h =  9
+      _items.Add(new PackingItem(10, 10, 9, _packingShape, 1000, 1)); // 10, V = 900,  A =  90, h = 10
+      _items.Add(new PackingItem(9, 9, 10, _packingShape, 1000, 2)); // 11,  V = 810,  A =  90, h =  9
+      _items.Add(new PackingItem(10, 9, 9, _packingShape, 1000, 3)); // 12,  V = 810,  A =  90, h =  9
+      _items.Add(new PackingItem(9, 10, 9, _packingShape, 1000, 4)); // 13,  V = 810,  A =  81, h = 10
+      _items.Add(new PackingItem(9, 9, 9, _packingShape, 1000, 0)); // 14,   V = 729,  A =  81, h =  9
+    }
+
+    
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByVolumeHeightExtension() {
+      Permutation actual = _items.SortByVolumeHeight();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7,  8, 10, 9, 13, 11, 12, 0, 2, 1, 14, 5, 3, 4, 6});
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+    
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByHeightVolumeExtension() {
+      Permutation actual = _items.SortByHeightVolume();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 8, 10, 13, 0, 2, 5, 9, 11, 12, 14, 1, 3, 4, 6 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByAreaHeightExtension() {
+      Permutation actual = _items.SortByAreaHeight();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 9, 1, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6});
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+    
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByHeightAreaExtension() {
+      Permutation actual = _items.SortByHeightArea();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 7, 8, 10, 13, 0, 2, 5, 9, 11, 12, 14, 1, 3, 4, 6});
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByClusteredAreaHeightExtension() {
+      Permutation actual = _items.SortByClusteredAreaHeight(_packingShape, 1.0);
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 0, 2, 5, 7, 8, 10, 13, 9, 11, 12, 14, 1, 3, 4, 6 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByClusteredHeightAreaExtension() {
+      Permutation actual = _items.SortByClusteredHeightArea(_packingShape, 1.0);
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 1, 7, 9, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialVolumeHeightExtension() {
+      Permutation actual = _items.SortByMaterialVolumeHeight();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 12, 2, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialHeightVolumeExtension() {
+      Permutation actual = _items.SortByMaterialHeightVolume();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 2, 12, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialAreaHeightExtension() {
+      Permutation actual = _items.SortByMaterialAreaHeight();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 12, 2, 1, 11, 6, 10, 0, 5, 9, 14, 4 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialHeightAreaExtension() {
+      Permutation actual = _items.SortByMaterialHeightArea();
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 7, 2, 12, 11, 1, 6, 10, 0, 5, 9, 14, 4 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialClusteredAreaHeightExtension() {
+      Permutation actual = _items.SortByMaterialClusteredAreaHeight(_packingShape, 1.0);
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 8, 13, 3, 2, 7, 12, 11, 1, 6, 0, 5, 10, 9, 14, 4 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }
+
+    [TestMethod]
+    [TestCategory("Problems.BinPacking.3D")]
+    [TestProperty("Time", "short")]
+    public void TestSortByMaterialClusteredHeightAreaExtension() {
+      Permutation actual = _items.SortByClusteredHeightArea(_packingShape, 1.0);
+      Permutation expected = new Permutation(PermutationTypes.Absolute, new int[] { 1, 7, 9, 8, 10, 11, 12, 13, 14, 0, 2, 3, 4, 5, 6 });
+      for (int i = 0; i < expected.Length; i++) {
+        Assert.AreEqual(expected[i], actual[i]);
+      }
+    }    
+  }
+}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ThreeDInstanceParserTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ThreeDInstanceParserTest.cs	(revision 15553)
+++ 	(revision )
@@ -1,99 +1,0 @@
-﻿using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.IO;
-using HeuristicLab.Problems.BinPacking3D.Instances;
-using System.Collections.Generic;
-using HeuristicLab.Problems.BinPacking3D;
-
-namespace HeuristicLab.Problems.BinPacking._3D.Tests {
-  [TestClass]
-  public class ThreeDInstanceParserTest {
-    private PackingShape _packingShape;
-    private IList<PackingItem> _items1;
-    private IList<PackingItem> _items2;
-
-    [TestInitialize]
-    public void Initializes() {
-      _packingShape = new PackingShape(22, 23, 21);
-      _items1 = new List<PackingItem>();
-
-      _items1.Add(new PackingItem(8, 10, 10, _packingShape, 800, 1)); // 0,  V = 800,  A =  80, h = 10
-      _items1.Add(new PackingItem(10, 8, 10, _packingShape, 800, 2)); // 1,  V = 800,  A = 100, h =  8
-      _items1.Add(new PackingItem(10, 10, 8, _packingShape, 800, 3)); // 2,  V = 800,  A =  80, h = 10
-      _items1.Add(new PackingItem(8, 8, 10,  _packingShape, 640, 4)); // 3,   V = 640,  A =  80, h =  8
-      _items1.Add(new PackingItem(10, 8, 8,  _packingShape, 640, 0)); // 4,   V = 640,  A =  80, h =  8
-      _items1.Add(new PackingItem(8, 10, 8,  _packingShape, 640, 1)); // 5,   V = 640,  A =  64, h = 10  
-      _items1.Add(new PackingItem(8, 8, 8,   _packingShape, 512, 2)); // 6,    V = 512,  A =  64, h =  8
-
-      _items1.Add(new PackingItem(10, 10, 10, _packingShape,1000,3)); // 7, V = 1000, A = 100, h = 10
-
-      _items1.Add(new PackingItem(9, 10, 10, _packingShape, 900, 4)); // 8,  V = 900,  A =  90, h = 10
-      _items1.Add(new PackingItem(10, 9, 10, _packingShape, 900, 0)); // 9,  V = 900,  A = 100, h =  9
-      _items1.Add(new PackingItem(10, 10, 9, _packingShape, 900, 1)); // 10, V = 900,  A =  90, h = 10
-      _items1.Add(new PackingItem(9, 9, 10,  _packingShape, 810, 2)); // 11,  V = 810,  A =  90, h =  9
-      _items1.Add(new PackingItem(10, 9, 9,  _packingShape, 810, 3)); // 12,  V = 810,  A =  90, h =  9
-      _items1.Add(new PackingItem(9, 10, 9,  _packingShape, 810, 4)); // 13,  V = 810,  A =  81, h = 10
-      _items1.Add(new PackingItem(9, 9, 9,   _packingShape, 729, 0)); // 14,   V = 729,  A =  81, h =  9
-
-      _items2 = new List<PackingItem>();
-      _items2.Add(new PackingItem(8, 10, 10, _packingShape, 800, 1)); // 0,  V = 800,  A =  80, h = 10
-      _items2.Add(new PackingItem(10, 8, 10, _packingShape, 800, 2)); // 1,  V = 800,  A = 100, h =  8
-      _items2.Add(new PackingItem(10, 10, 8, _packingShape, 800, 3)); // 2,  V = 800,  A =  80, h = 10
-      _items2.Add(new PackingItem(8, 8, 10, _packingShape, 640, 4)); // 3,   V = 640,  A =  80, h =  8
-      _items2.Add(new PackingItem(10, 8, 8, _packingShape, 640, 0)); // 4,   V = 640,  A =  80, h =  8
-      _items2.Add(new PackingItem(8, 10, 8, _packingShape, 640, 1)); // 5,   V = 640,  A =  64, h = 10  
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestParse() {
-      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\Parser\3D-UnitTestParser1.txt";
-      ThreeDInstanceParser parser = new ThreeDInstanceParser();
-
-      using (var fileStream = File.Open(path, FileMode.Open)) {
-        parser.Parse(fileStream);
-      }
-      
-      Assert.AreEqual(_packingShape.Width, parser.Bin.Width);
-      Assert.AreEqual(_packingShape.Height, parser.Bin.Height);
-      Assert.AreEqual(_packingShape.Depth, parser.Bin.Depth);
-
-      Assert.AreEqual(_items1.Count, parser.Items.Count);
-      for (int i = 0; i < parser.Items.Count; i++) {
-        PackingItem expected = _items1[i];
-        PackingItem actual = parser.Items[i];
-        Assert.AreEqual(expected.Width, actual.Width);
-        Assert.AreEqual(expected.Height, actual.Height);
-        Assert.AreEqual(expected.Depth, actual.Depth);
-        Assert.AreEqual(expected.Material, actual.Material);
-        Assert.AreEqual(expected.Weight, actual.Weight);
-      }
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking.3D")]
-    public void TestParseUncompleteFile() {
-      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\TestInstances\Parser\3D-UnitTestParser2.txt";
-      ThreeDInstanceParser parser = new ThreeDInstanceParser();
-
-      using (var fileStream = File.Open(path, FileMode.Open)) {
-        parser.Parse(fileStream);
-      }
-
-      Assert.AreEqual(_packingShape.Width, parser.Bin.Width);
-      Assert.AreEqual(_packingShape.Height, parser.Bin.Height);
-      Assert.AreEqual(_packingShape.Depth, parser.Bin.Depth);
-
-      Assert.AreEqual(_items2.Count, parser.Items.Count);
-      for (int i = 0; i < parser.Items.Count; i++) {
-        PackingItem expected = _items2[i];
-        PackingItem actual = parser.Items[i];
-        Assert.AreEqual(expected.Width, actual.Width);
-        Assert.AreEqual(expected.Height, actual.Height);
-        Assert.AreEqual(expected.Depth, actual.Depth);
-        Assert.AreEqual(expected.Material, actual.Material);
-        Assert.AreEqual(expected.Weight, actual.Weight);
-      }
-    }
-  }
-}
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/Utils/TestUtils.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/Utils/TestUtils.cs	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/Utils/TestUtils.cs	(revision 15554)
@@ -13,4 +13,12 @@
     }
 
+    /// <summary>
+    /// Invokes a private method of an given object by using reflection
+    /// </summary>
+    /// <param name="type"></param>
+    /// <param name="o"></param>
+    /// <param name="methodName"></param>
+    /// <param name="parameters"></param>
+    /// <returns></returns>
     public static object InvokeMethod(Type type, object o, string methodName, object[] parameters) {
       var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Tests.csproj
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15553)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15554)
@@ -583,8 +583,14 @@
     <Compile Include="HeuristicLab.PluginInfraStructure-3.3\InstallationManagerTest.cs" />
     <Compile Include="HeuristicLab.PluginInfraStructure-3.3\TypeExtensionsTest.cs" />
-    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\RandomInstanceProviderTest.cs" />
-    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\PermutationSortingTest.cs" />
-    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\ExtremePointAlgorithmTest.cs" />
-    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\ThreeDInstanceParserTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\ExtremePointCreation\TestLineProjectionBasedEPCreator.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Geometry\Edge3DTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Geometry\Line3DTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Geometry\Plane3DTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Geometry\Vector3DTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Instances\RandomInstanceProviderTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Sorting\PermutationSortingTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Algorithms\ExtremePointAlgorithmTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\ResidualSpaceCalculation\ResidualSpaceCalculatorTest.cs" />
+    <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\3D\Instances\ThreeDInstanceParserTest.cs" />
     <Compile Include="HeuristicLab.Problems.Bin-Packing-3.3\Utils\TestUtils.cs" />
     <Compile Include="HeuristicLab.Problems.DataAnalysis-3.4\ThresholdCalculatorsTest.cs" />
