Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/BinPacking3D.cs	(revision 15471)
@@ -67,4 +67,10 @@
     #region New methods for bin packer class
 
+    /// <summary>
+    /// Puts a given item into the bin packing at the given position.
+    /// </summary>
+    /// <param name="itemID">Offset in the internal item array</param>
+    /// <param name="item">Item</param>
+    /// <param name="position">Position of the item in the bin packing</param>
     public override void PackItem(int itemID, PackingItem item, PackingPosition position) {
       Items[itemID] = item;
@@ -107,44 +113,6 @@
       AddExtremePoint(ep2);
       AddExtremePoint(ep3);
-
-      /*
-      ExtremePoints.Add(ep1);
-      ExtremePoints.Add(ep2);
-      ExtremePoints.Add(ep3);
-
-      var rs1 = CalculateResidualSpace(CreateRs(ep1));
-      var rs2 = CalculateResidualSpace(CreateRs(ep2));
-      var rs3 = CalculateResidualSpace(CreateRs(ep3));
-      ResidualSpace.Add(ep1, rs1);
-      ResidualSpace.Add(ep2, rs2);
-      ResidualSpace.Add(ep3, rs3);*/
-    }
-
-
-    /*private bool AddExtremePoint(PackingPosition position) {
-      if ()
-
-      return true;
-    }
-
-    
-    private bool AddExtremePoint(PackingPosition pos) {
-      if (ExtremePoints.Add(pos)) {
-        var rs = CalculateResidualSpace(new Vector3D(pos));
-        ResidualSpace.Add(pos, rs);
-        // Check if existing extreme points are shadowed by the new point
-        // That is, their residual space fit entirely into the residual space of the new point
-        foreach (var ep in ExtremePoints.Where(x => x != pos && new Vector3D(x).IsInside(pos, rs)).ToList()) {
-          if (IsWithinResidualSpaceOfAnotherExtremePoint(new Vector3D(ep), ResidualSpace[ep], pos, rs)) {
-            ExtremePoints.Remove(ep);
-            ResidualSpace.Remove(ep);
-          }
-        }
-        return true;
-      }
-      return false;
-    }*/
-
-
+    }
+        
     private Tuple<int, int, int> CalculateResidualSpace(Vector3D pos) {
       var itemPos = Items.Select(x => new { Item = x.Value, Position = Positions[x.Key] });
@@ -164,12 +132,8 @@
         }
       }
-
-      
       
       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);
     }
@@ -491,8 +455,19 @@
     }
 
+    /// <summary>
+    /// Returns true if all values of a given tuple are not zero
+    /// </summary>
+    /// <param name="rs">Tuple with three integer values which represents a residual space</param>
+    /// <returns></returns>
     private bool IsNonZero(Tuple<int, int, int> rs) {
       return rs.Item1 > 0 && rs.Item2 > 0 && rs.Item3 > 0;
     }
 
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="pos"></param>
+    /// <param name="residualSpace"></param>
+    /// <returns></returns>
     private bool IsWithinResidualSpaceOfAnotherExtremePoint(Vector3D pos, Tuple<int, int, int> residualSpace) {
       var eps = ExtremePoints.Where(x => !pos.Equals(x) && pos.IsInside(x, ResidualSpace[x]));
@@ -505,10 +480,15 @@
     }
 
+    /// <summary>
+    /// Adds an extrem point to the extreme point collection of the bin packing.
+    /// </summary>
+    /// <param name="pos">Position of the new extreme point</param>
+    /// <returns>Retruns true if the extreme point could be added</returns>
     private bool AddExtremePoint(PackingPosition pos) {
       if (ExtremePoints.Add(pos)) {
         var rs = CalculateResidualSpace(new Vector3D(pos));
         ResidualSpace.Add(pos, rs);
-        // Check if existing extreme points are shadowed by the new point
-        // That is, their residual space fit entirely into the residual space of the new point
+        // 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 ExtremePoints.Where(x => x != pos && new Vector3D(x).IsInside(pos, rs)).ToList()) {
           if (IsWithinResidualSpaceOfAnotherExtremePoint(new Vector3D(ep), ResidualSpace[ep], pos, rs)) {
@@ -521,13 +501,5 @@
       return false;
     }
-
-    private Tuple<int, int, int> CalculateResidualSpace1(Vector3D pos) {
-      var itemPos = Items.Select(x => new { Item = x.Value, Position = Positions[x.Key] });
-      var rightLimit = ProjectRight(pos);
-      var upLimit = ProjectUp(pos);
-      var forwardLimit = ProjectForward(pos);
-      return Tuple.Create(rightLimit.X - pos.X, upLimit.Y - pos.Y, forwardLimit.Z - pos.Z);
-    }
-
+        
     #region Projections
 
@@ -719,4 +691,9 @@
 
 
+    /// <summary>
+    /// Updates the resiual space for a packing item.
+    /// </summary>
+    /// <param name="item"></param>
+    /// <param name="pos"></param>
     public void UpdateResidualSpace(PackingItem item, PackingPosition pos) {
       foreach (var ep in ExtremePoints.ToList()) {
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest.txt
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest.txt	(revision 15471)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest.txt	(revision 15471)
@@ -0,0 +1,21 @@
+BIN DIMENSION
+Length	Width	Height	MaxWeight
+20	20	20	5832
+ITEMS
+ID	Pcs	Length	Width	Height	Weight	Stack	Layer	Rotate	Tilt
+0	1	10	8	10	800	1	0	0	0
+1	1	10	10	8	800	2	0	0	0
+2	1	8	10	10	800	3	0	0	0
+3	1	10	8	8	640	4	0	0	0
+4	1	8	8	10	640	0	0	0	0
+5	1	8	10	8	640	1	0	0	0
+6	1	8	8	8	512	0	0	0	0
+7	1	10	10	10	1000	2	0	0	0
+8	1	10	10	9	900	3	0	0	0
+9	1	10	9	10	900	4	0	0	0
+10	1	9	10	10	900	0	0	0	0
+11	1	10	9	9	810	1	0	0	0
+12	1	9	10	9	810	2	0	0	0
+13	1	10	9	9	810	3	0	0	0
+14	1	9	9	9	729	4	0	0	0
+
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest1.txt
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest1.txt	(revision 15471)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-UnitTest1.txt	(revision 15471)
@@ -0,0 +1,21 @@
+BIN DIMENSION
+Length	Width	Height	MaxWeight
+20	20	20	5832
+ITEMS
+ID	Pcs	Length	Width	Height	Weight	Stack	Layer	Rotate	Tilt
+0	1	10	8	10	800	1	0	0	0
+1	1	10	10	8	800	2	0	0	0
+2	1	8	10	10	800	3	0	0	0
+3	1	10	8	8	640	4	0	0	0
+4	1	8	8	10	640	0	0	0	0
+5	1	8	10	8	640	1	0	0	0
+6	1	8	8	8	512	0	0	0	0
+7	1	10	10	10	1000	2	0	0	0
+8	1	10	10	9	900	3	0	0	0
+9	1	10	9	10	900	4	0	0	0
+10	1	9	10	10	900	0	0	0	0
+11	1	10	9	9	810	1	0	0	0
+12	1	9	10	9	810	2	0	0	0
+13	1	10	9	9	810	3	0	0	0
+14	1	9	9	9	729	4	0	0	0
+
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/RealWorldContainerPackingInstanceProvider.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/RealWorldContainerPackingInstanceProvider.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/RealWorldContainerPackingInstanceProvider.cs	(revision 15471)
@@ -102,5 +102,4 @@
         var parser = new ThreeDInstanceParser();
         parser.Parse(stream);
-
         return new BPPData() {
           Name = Path.GetFileNameWithoutExtension(path),
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IntegerVectorEncoding/ThreeDInstanceParser.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IntegerVectorEncoding/ThreeDInstanceParser.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/IntegerVectorEncoding/ThreeDInstanceParser.cs	(revision 15471)
@@ -64,10 +64,13 @@
       var next = reader.Read();
       var builder = new StringBuilder();
-      while (next >= 0 && !char.IsDigit((char)next)) next = reader.Read();
-      if (next == -1) throw new InvalidOperationException("No further integer available");
+      while (next >= 0 && !char.IsDigit((char)next))
+        next = reader.Read();
+      if (next == -1)
+        throw new InvalidOperationException("No further integer available");
       while (char.IsDigit((char)next)) {
         builder.Append((char)next);
         next = reader.Read();
-        if (next == -1) break;
+        if (next == -1)
+          break;
       }
       return int.Parse(builder.ToString());
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 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPacker.cs	(revision 15471)
@@ -44,9 +44,7 @@
     /// <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>
+    /// <returns>Returns a collection of bin packing 3d objects. Each object represents a bin and the packed items</returns>
     public abstract IList<BinPacking3D> PackItems(Permutation sortedItems, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints);
-
     
-
     /// <summary>
     /// Pack a given item into a given bin and updates the residual space and the extreme points
@@ -78,6 +76,5 @@
         packingItem.TargetBin, packingItem.Weight, packingItem.Material);
 
-      // The extremepoints are sortet by Z, X, Y
-
+      // The extremepoints are sortet by Y / Z / X
       return packingBin.ExtremePoints.Where(x => packingBin.IsPositionFeasible(newItem, x, useStackingConstraints)).FirstOrDefault();
     }
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 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFactory.cs	(revision 15471)
@@ -16,5 +16,5 @@
     /// </summary>
     /// <param name="fittingMethod"></param>
-    /// <returns></returns>
+    /// <returns>Returns a new BinPacker depending on the given fitting method</returns>
     public static BinPacker CreateBinPacker(FittingMethod fittingMethod) {
       BinPacker binPacker = null;
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 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFirstFit.cs	(revision 15471)
@@ -38,5 +38,5 @@
 
     /// <summary>
-    /// Packs the items of the object by using a first fit algorithm into an amount of bins and returns them
+    /// Packs the items of the object by using a first fit algorithm into an amount of bins and returns them.
     /// </summary>
     /// <returns>Returns a collection of bin packing 3d objects. Each object represents a bin and the packed items</returns>
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 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerFreeVolumeBestFit.cs	(revision 15471)
@@ -36,8 +36,19 @@
     public BinPackerFreeVolumeBestFit() : base() { }
 
+    /// <summary>
+    /// Packs all items by using a free volume best fit strategy.
+    /// If there is no bin packing item, a new one will be created an the current item will be packed into it.
+    /// If there exists at least on bin packing item in the packing list they are being sortet by their free volume ascending. 
+    /// The current item will be packed into the bin packing with the fewest free volume and enought space for placing it.
+    /// If an item could not be placed in any bin packing, a new one will be created for the item.
+    /// </summary>
+    /// <param name="sortedItems"></param>
+    /// <param name="binShape"></param>
+    /// <param name="items"></param>
+    /// <param name="useStackingConstraints"></param>
+    /// <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, bool useStackingConstraints) {
       IList<BinPacking3D> packingList = new List<BinPacking3D>();
       IList<int> remainingIds = new List<int>(sortedItems);
-
 
       foreach (int remainingId in remainingIds) {
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 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Packer/BinPackerResidualSpaceBestFit.cs	(revision 15471)
@@ -34,8 +34,6 @@
   public class BinPackerResidualSpaceBestFit : BinPacker {
 
-    public BinPackerResidualSpaceBestFit() : base() { }/*
-    public BinPackerResidualSpaceBestFit(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints)
-      : base(permutation, binShape, items, useStackingConstraints) { }
-      */
+    public BinPackerResidualSpaceBestFit() : base() { }
+
     /// <summary>
     /// Packs the items into the bins by using a best fit residual space algorithm.
@@ -43,5 +41,5 @@
     /// Each residual space belongs to an extreme point.
     /// </summary>
-    /// <returns></returns>
+    /// <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, bool useStackingConstraints) {
       IList<BinPacking3D> packingList = new List<BinPacking3D>();
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PackingPosition.cs	(revision 15471)
@@ -105,9 +105,15 @@
     /// <summary>
     /// Compares two packing positions by their coordinates. 
-    /// The order of comparing is z -> x -> y.
+    /// The order of comparing is y (height) -> z (depth) -> x (width).
     /// </summary>
     /// <param name="other"></param>
     /// <returns></returns>
     public int CompareTo(PackingPosition other) {
+      int result = Y.CompareTo(other.Y);
+      if (result == 0)
+        result = Z.CompareTo(other.Z);
+      if (result == 0)
+        result = X.CompareTo(other.X);
+      /*
       int result = Z.CompareTo(other.Z);
       if (result == 0)
@@ -115,5 +121,5 @@
       if (result == 0)
         result = Y.CompareTo(other.Y);
-      
+      */
       return result;
 
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ProblemBase.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ProblemBase.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/ProblemBase.cs	(revision 15471)
@@ -236,5 +236,4 @@
       BinShape = data.BinShape;
       var items = new ItemList<PackingItem>(data.Items);
-      items.Sort((x, y) => y.CompareTo(x));
       Items = items.AsReadOnly();
 
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Sorting/PackingItemSorter.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Sorting/PackingItemSorter.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Sorting/PackingItemSorter.cs	(revision 15471)
@@ -8,5 +8,15 @@
 
 namespace HeuristicLab.Problems.BinPacking3D.Sorting {
+
+  /// <summary>
+  /// This is a extension class for sorting a permutation.
+  /// </summary>
   public static class PackingItemSorter {
+
+    /// <summary>
+    /// Sorts a given permutation first by the volume and secoundly by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByVolumeHeight(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -17,4 +27,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation first by the heigth and secoundly by the volume.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByHeightVolume(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -25,4 +40,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation first by the area and secondly by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByAreaHeight(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -33,4 +53,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permuation first by the height and secoundly by the area.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByHeightArea(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -41,4 +66,13 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation. The items are being grouped by the cluster id.
+    /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta))
+    /// The permutation is first being sorted by the area and secoundly by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <param name="bin">The bin is needed for building the cluster</param>
+    /// <param name="delta">The delta is needed for building the cluster</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {
       double clusterRange = bin.Width * bin.Depth * delta;
@@ -52,4 +86,13 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation. The items are being grouped by the cluster id.
+    /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta))
+    /// The permutation is first being sorted by the height and secoundly by the area.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <param name="bin">The bin is needed for building the cluster</param>
+    /// <param name="delta">The delta is needed for building the cluster</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByClusteredHeightArea(this IList<PackingItem> items, PackingShape bin, double delta) {
       double clusterRange2 = bin.Height * delta;
@@ -63,4 +106,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation first by the material, secoundly by the volume and finally by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialVolumeHeight(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -72,4 +120,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation first by the material, secoundly by the heigth and finally by the volume.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialHeightVolume(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -81,4 +134,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation first by the material, secoundly by the area and finally by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialAreaHeight(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -90,4 +148,9 @@
     }
 
+    /// <summary>
+    /// Sorts a given permuation first by the material, secoundly by the height and finally by the area.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialHeightArea(this IList<PackingItem> items) {
       return new Permutation(PermutationTypes.Absolute,
@@ -99,4 +162,13 @@
     }
 
+    /// <summary>
+    /// Sorts a given permutation. The items are being grouped by the cluster id.
+    /// The cluster id is calulated as followed: clusterId = Ceiling( (width * depth) / (width * depth * delta))
+    /// The permutation is being clusterd by the area, first sorted by the material, secoundly by the height.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <param name="bin">The bin is needed for building the cluster</param>
+    /// <param name="delta">The delta is needed for building the cluster</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {
       double clusterRange = bin.Width * bin.Depth * delta;
@@ -104,10 +176,19 @@
                 items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Width * v.Depth / clusterRange)) })
                     .GroupBy(x => x.ClusterId)
-                    .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Height).ToList() })
-                    .OrderByDescending(x => x.Cluster)
-                    .SelectMany(x => x.Items)
-                    .Select(x => x.Index).ToArray());
-    }
-
+                    .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Height).ToList() })
+                    .OrderByDescending(x => x.Cluster)
+                    .SelectMany(x => x.Items)
+                    .Select(x => x.Index).ToArray());
+    }
+
+    /// <summary>
+    /// Sorts a given permutation. The items are being grouped by the cluster id.
+    /// The cluster id is calulated as followed: clusterId = Ceiling( (height) / (height * delta))
+    /// The permutation is being clusterd by the height, first sorted by the material, secoundly by the area.
+    /// </summary>
+    /// <param name="items">Permuation which should be sorted</param>
+    /// <param name="bin">The bin is needed for building the cluster</param>
+    /// <param name="delta">The delta is needed for building the cluster</param>
+    /// <returns>A new sorted permutation</returns>
     public static Permutation SortByMaterialClusteredHeightArea(this IList<PackingItem> items, PackingShape bin,  double delta) {
       double clusterRange2 = bin.Height * delta;
@@ -115,5 +196,5 @@
                 items.Select((v, i) => new { Index = i, Item = v, ClusterId = (int)(Math.Ceiling(v.Height / clusterRange2)) })
                     .GroupBy(x => x.ClusterId)
-                    .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(y => y.Item.Depth * y.Item.Width).ToList() })
+                    .Select(x => new { Cluster = x.Key, Items = x.OrderByDescending(z => z.Item.Material).ThenByDescending(y => y.Item.Depth * y.Item.Width).ToList() })
                     .OrderByDescending(x => x.Cluster)
                     .SelectMany(x => x.Items)
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/Algorithms/3D/ExtremePointAlgorithm.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/Algorithms/3D/ExtremePointAlgorithm.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/Algorithms/3D/ExtremePointAlgorithm.cs	(revision 15471)
@@ -182,4 +182,5 @@
           IDecoder<Permutation> decoder = new ExtremePointPermutationDecoder(BinPackerFactory.CreateBinPacker(fit));
           Permutation sortedItems;
+                    
           if (SortByMaterialParameter.Value.Value) {
             sortedItems = SortItemsByMaterialAndSortingMethod(bin, items, sort, DeltaParameter.Value.Value);
@@ -187,7 +188,7 @@
             sortedItems = SortItemsBySortingMethod(bin, items, sort, DeltaParameter.Value.Value);
           }
-                    
+          
           var result = Optimize(sortedItems, bin, items, Problem.UseStackingConstraints, decoder, Problem.SolutionEvaluator);
-
+          
           if (double.IsNaN(result.Item2) || double.IsInfinity(result.Item2)) {
             continue;
Index: branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/AlgorithmTest.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/AlgorithmTest.cs	(revision 15463)
+++ 	(revision )
@@ -1,267 +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 AlgorithmTest {
-
-    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\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}: \t{referenceValue} \t {(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, 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, 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, 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, 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, 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 });
-      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/ExtremePointAlgorithmTest.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointAlgorithmTest.cs	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/ExtremePointAlgorithmTest.cs	(revision 15471)
@@ -6,4 +6,5 @@
 using HeuristicLab.Problems.BinPacking._3D.Utils.Tests;
 using System.Threading;
+using System.Linq;
 
 namespace HeuristicLab.Problems.BinPacking._3D.Tests {
@@ -13,4 +14,5 @@
     private PackingShape _packingShape1;
     private PackingShape _packingShape2;
+    private PackingShape _packingShape3;
     private IList<PackingItem> _items;
     private ExtremePointAlgorithm _extremPointAlgorithm;
@@ -20,4 +22,5 @@
       _packingShape1 = new PackingShape(19, 19, 19);
       _packingShape2 = new PackingShape(18, 18, 18);
+      _packingShape3 = new PackingShape(20, 20, 20);
       _items = new List<PackingItem>();
 
@@ -47,16 +50,48 @@
     [TestMethod]
     [TestCategory("Problems.BinPacking.3D")]
-    public void TestMethod1() {
-      object[] parameters = new object[] { _packingShape1, _items, new SortingMethod[] { SortingMethod.Given }, new FittingMethod[] { FittingMethod.FirstFit }, new CancellationToken()};
+    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?>;
-      //InvokeMethod();
 
-      var bins = result.Item1.Bins;
-      var items0 = bins[0].Items;
-      var positions0 = bins[0].Positions;
-      var items1 = bins[1].Items;
-      var positions1 = bins[1].Positions;
+      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++;
+      }
 
-      var s = 1;
+      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/RandomInstanceProviderTest.cs
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/RandomInstanceProviderTest.cs	(revision 15471)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/RandomInstanceProviderTest.cs	(revision 15471)
@@ -0,0 +1,277 @@
+﻿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\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.Tests.csproj
===================================================================
--- branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15463)
+++ branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Tests.csproj	(revision 15471)
@@ -583,5 +583,5 @@
     <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\AlgorithmTest.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" />
