Index: /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-Instance-A-1.txt
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-Instance-A-1.txt	(revision 15463)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/3D-Instance-A-1.txt	(revision 15463)
@@ -0,0 +1,11 @@
+BIN DIMENSION
+Length	Width	Height	MaxWeight
+1350	250	300	9000
+ITEMS
+ID	Pcs	Length	Width	Height	Weight	Stack	Layer	Rotate	Tilt
+0	21	170	250	280	1500	0	0	1	0
+1	18	250	200	190	600	0	0	1	0
+2	21	90	125	190	150	0	0	1	0
+3	21	710	200	50	300	1	2	0	1
+4	24	1000	200	20	100	1	1	0	1
+5	6	280	250	250	1000	0	0	0	0
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/ThreeDInstanceParser.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/Instances/ThreeDInstanceParser.cs	(revision 15462)
+++ 	(revision )
@@ -1,76 +1,0 @@
-﻿#region License Information
-
-/* HeuristicLab
- * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  public class ThreeDInstanceParser {
-    public PackingShape Bin { get; private set; }
-    public List<PackingItem> Items { get; private set; }
-
-    public void Parse(Stream stream) {
-      var reader = new StreamReader(stream);
-      var length = GetNextInteger(reader);
-      var width = GetNextInteger(reader);
-      var height = GetNextInteger(reader);
-      var maxWeight = GetNextInteger(reader);
-      Bin = new PackingShape(width, height, length);
-      Items = new List<PackingItem>();
-      while (true) {
-        try {
-          var id = GetNextInteger(reader);
-          var pieces = GetNextInteger(reader);
-          length = GetNextInteger(reader);
-          width = GetNextInteger(reader);
-          height = GetNextInteger(reader);
-          var weight = GetNextInteger(reader);
-          var stack = GetNextInteger(reader);
-          var material = GetNextInteger(reader);
-          var rotate = GetNextInteger(reader);
-          var tilt = GetNextInteger(reader);
-          for (var i = 0; i < pieces; i++) {
-            Items.Add(new PackingItem(width, height, length, Bin, weight, material));
-          }
-        } catch (InvalidOperationException) {
-          break;
-        }
-      }
-    }
-
-    private int GetNextInteger(StreamReader reader) {
-      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 (char.IsDigit((char)next)) {
-        builder.Append((char)next);
-        next = reader.Read();
-        if (next == -1) break;
-      }
-      return int.Parse(builder.ToString());
-    }
-  }
-}
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 15463)
@@ -0,0 +1,76 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+
+namespace HeuristicLab.Problems.BinPacking3D {
+  public class ThreeDInstanceParser {
+    public PackingShape Bin { get; private set; }
+    public List<PackingItem> Items { get; private set; }
+
+    public void Parse(Stream stream) {
+      var reader = new StreamReader(stream);
+      var length = GetNextInteger(reader);
+      var width = GetNextInteger(reader);
+      var height = GetNextInteger(reader);
+      var maxWeight = GetNextInteger(reader);
+      Bin = new PackingShape(width, height, length);
+      Items = new List<PackingItem>();
+      while (true) {
+        try {
+          var id = GetNextInteger(reader);
+          var pieces = GetNextInteger(reader);
+          length = GetNextInteger(reader);
+          width = GetNextInteger(reader);
+          height = GetNextInteger(reader);
+          var weight = GetNextInteger(reader);
+          var stack = GetNextInteger(reader);
+          var material = GetNextInteger(reader);
+          var rotate = GetNextInteger(reader);
+          var tilt = GetNextInteger(reader);
+          for (var i = 0; i < pieces; i++) {
+            Items.Add(new PackingItem(width, height, length, Bin, weight, material));
+          }
+        } catch (InvalidOperationException) {
+          break;
+        }
+      }
+    }
+
+    private int GetNextInteger(StreamReader reader) {
+      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 (char.IsDigit((char)next)) {
+        builder.Append((char)next);
+        next = reader.Read();
+        if (next == -1) break;
+      }
+      return int.Parse(builder.ToString());
+    }
+  }
+}
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 15463)
@@ -0,0 +1,37 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Problems.BinPacking3D.Packer {
+
+  /// <summary>
+  /// This class can be used for creating bin packer insances
+  /// </summary>
+  public static class BinPackerFactory {
+
+    /// <summary>
+    /// Returns the bin packer depending on the given fitting method
+    /// </summary>
+    /// <param name="fittingMethod"></param>
+    /// <returns></returns>
+    public static BinPacker CreateBinPacker(FittingMethod fittingMethod) {
+      BinPacker binPacker = null;
+      switch (fittingMethod) {
+        case FittingMethod.FirstFit:
+          binPacker = new BinPackerFirstFit();
+          break;
+        case FittingMethod.FreeVolumeBestFit:
+          binPacker = new BinPackerFreeVolumeBestFit();
+          break;
+        case FittingMethod.ResidualSpaceBestFit:
+          binPacker = new BinPackerResidualSpaceBestFit();
+          break;
+        default:
+          throw new ArgumentException("Unknown fitting method: " + fittingMethod);
+      }
+      return binPacker;
+    }
+  }
+}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/BottomLeftPermutationDecoder.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/BottomLeftPermutationDecoder.cs	(revision 15462)
+++ 	(revision )
@@ -1,55 +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.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Common;
-using System.Collections.Generic;
-using HeuristicLab.Encodings.PermutationEncoding;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  [Item("Bottom-left Permutation Decoder (3d)", "Decodes the permutation and creates a packing solution candidate")]
-  [StorableClass]
-  public class BottomLeftPermutationDecoder : Item, IDecoder<Permutation> {
-
-    [StorableConstructor]
-    protected BottomLeftPermutationDecoder(bool deserializing) : base(deserializing) { }
-    protected BottomLeftPermutationDecoder(BottomLeftPermutationDecoder original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public BottomLeftPermutationDecoder() : base() { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new BottomLeftPermutationDecoder(this, cloner);
-    }
-
-    public Solution Decode(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      Solution result = new Solution(binShape, useExtremePoints: false, stackingConstraints: useStackingConstraints);
-      IList<int> remainingIDs = new List<int>(permutation);
-      while (remainingIDs.Count > 0) {
-        var bp = new BinPacking3D(binShape);
-        bp.SlidingBasedPacking(ref remainingIDs, items, useStackingConstraints);
-        result.Bins.Add(bp);
-      }
-      result.UpdateBinPackings();
-      return result;
-    }
-  }
-}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ExtremePointPermutationDecoder.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ExtremePointPermutationDecoder.cs	(revision 15462)
+++ 	(revision )
@@ -1,62 +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 System;
-using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Common;
-using System.Collections.Generic;
-using HeuristicLab.Encodings.PermutationEncoding;
-using System.Linq;
-
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  [Item("Extreme-point Permutation Decoder (3d)", "Decodes the permutation and creates a packing solution candidate")]
-  [StorableClass]
-  public class ExtremePointPermutationDecoder : ExtremePointPermutationDecoderBase {
-
-    [StorableConstructor]
-    protected ExtremePointPermutationDecoder(bool deserializing) : base(deserializing) { }
-    protected ExtremePointPermutationDecoder(ExtremePointPermutationDecoder original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ExtremePointPermutationDecoder() : base() { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ExtremePointPermutationDecoder(this, cloner);
-    }
-
-    public override Solution Decode(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      return Apply(permutation, binShape, items, useStackingConstraints);
-    }
-
-    public static Solution Apply(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      Solution result = new Solution(binShape, useExtremePoints: true, stackingConstraints: useStackingConstraints);
-      IList<int> remainingIDs = new List<int>(permutation);
-      while (remainingIDs.Count > 0) {
-        var bp = new BinPacking3D(binShape);
-        bp.ExtremePointBasedPacking(ref remainingIDs, items, stackingConstraints: useStackingConstraints);
-        result.Bins.Add(bp);
-      }
-      result.UpdateBinPackings();
-      return result;
-    }
-  }
-}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ExtremePointPermutationDecoderBase.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ExtremePointPermutationDecoderBase.cs	(revision 15462)
+++ 	(revision )
@@ -1,42 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
- 
-using System.Collections.Generic;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  [Item("Extreme-point Permutation Decoder (3d) Base", "Base class for decoders")]
-  [StorableClass]
-  public abstract class ExtremePointPermutationDecoderBase : Item, IDecoder<Permutation> {
-
-    [StorableConstructor]
-    protected ExtremePointPermutationDecoderBase(bool deserializing) : base(deserializing) { }
-    protected ExtremePointPermutationDecoderBase(ExtremePointPermutationDecoderBase original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ExtremePointPermutationDecoderBase() : base() { }
-
-    public abstract Solution Decode(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints);
-  }
-}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/FreeVolumeBestFitExtremePointPermutationDecoder.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/FreeVolumeBestFitExtremePointPermutationDecoder.cs	(revision 15462)
+++ 	(revision )
@@ -1,79 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  [Item("Free Volume Best Fit Extreme-point Permutation Decoder (3d)", "Decodes the permutation and creates a packing solution candidate")]
-  [StorableClass]
-  public class FreeVolumeBestFitExtremePointPermutationDecoder : ExtremePointPermutationDecoderBase {
-
-    [StorableConstructor]
-    protected FreeVolumeBestFitExtremePointPermutationDecoder(bool deserializing) : base(deserializing) { }
-    protected FreeVolumeBestFitExtremePointPermutationDecoder(FreeVolumeBestFitExtremePointPermutationDecoder original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public FreeVolumeBestFitExtremePointPermutationDecoder() : base() { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new FreeVolumeBestFitExtremePointPermutationDecoder(this, cloner);
-    }
-
-    public override Solution Decode(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      return Apply(permutation, binShape, items, useStackingConstraints);
-    }
-
-    public static Solution Apply(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      Solution result = new Solution(binShape, useExtremePoints: true, stackingConstraints: useStackingConstraints);
-      IList<int> remainingIDs = new List<int>(permutation);
-      var bpg = new BinPacking3D(binShape);
-      bpg.ExtremePointBasedPacking(ref remainingIDs, items, stackingConstraints: useStackingConstraints);
-      result.Bins.Add(bpg);
-      foreach (int ID in remainingIDs) {
-        var sortedBins = result.Bins.OrderBy(x => x.FreeVolume);
-        var item = items[ID];
-        var posFound = false;
-        foreach (var bp in sortedBins) {
-          var pos = bp.FindExtremePointForItem(item, false, useStackingConstraints);
-          posFound = pos != null;
-          if (posFound) {
-            bp.PackItem(ID, item, pos);
-            break;
-          }
-        }
-        if (!posFound) {
-          var bp = new BinPacking3D(binShape);
-          var pos = bp.FindExtremePointForItem(item, false, useStackingConstraints);
-          if (pos == null) throw new InvalidOperationException("Item " + ID + " cannot be packed in empty bin.");
-          bp.PackItem(ID, item, pos);
-          result.Bins.Add(bp);
-        }
-      }
-      result.UpdateBinPackings();
-      return result;
-    }
-  }
-}
Index: anches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ResidualSpaceBestFitExtremePointPermutationDecoder.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Problems.BinPacking/3.3/3D/PermutationEncoding/ResidualSpaceBestFitExtremePointPermutationDecoder.cs	(revision 15462)
+++ 	(revision )
@@ -1,96 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Encodings.PermutationEncoding;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-
-namespace HeuristicLab.Problems.BinPacking3D {
-  [Item("Residual Space Best Fit Extreme-point Permutation Decoder (3d)", "Decodes the permutation and creates a packing solution candidate")]
-  [StorableClass]
-  public class ResidualSpaceBestFitExtremePointPermutationDecoder : ExtremePointPermutationDecoderBase {
-
-    [StorableConstructor]
-    protected ResidualSpaceBestFitExtremePointPermutationDecoder(bool deserializing) : base(deserializing) { }
-    protected ResidualSpaceBestFitExtremePointPermutationDecoder(ResidualSpaceBestFitExtremePointPermutationDecoder original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public ResidualSpaceBestFitExtremePointPermutationDecoder() : base() { }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ResidualSpaceBestFitExtremePointPermutationDecoder(this, cloner);
-    }
-
-    public override Solution Decode(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      return Apply(permutation, binShape, items, useStackingConstraints);
-    }
-
-    public static Solution Apply(Permutation permutation, PackingShape binShape, IList<PackingItem> items, bool useStackingConstraints) {
-      Solution result = new Solution(binShape, useExtremePoints: true, stackingConstraints: useStackingConstraints);
-      IList<int> remainingIDs = new List<int>(permutation);
-      var bpg = new BinPacking3D(binShape);
-      bpg.ExtremePointBasedPacking(ref remainingIDs, items, stackingConstraints: useStackingConstraints);
-      result.Bins.Add(bpg);
-      foreach (int ID in remainingIDs) {
-        var item = items[ID];
-        var points = GetResidualSpaceAllPoints(result, item);
-        var sortedPoints = points.OrderBy(x => x.Item3);
-        var packed = false;
-        foreach (var p in sortedPoints) {
-          packed = p.Item1.PackItemIfFeasible(ID, item, p.Item2, useStackingConstraints);
-          if (packed) break;
-        }
-        if (!packed) {
-          // pack item in a new bin
-          var bp = new BinPacking3D(binShape);
-          var positionFound = bp.FindExtremePointForItem(item, false, useStackingConstraints);
-          if (positionFound != null) {
-            bp.PackItem(ID, item, positionFound);
-          } else throw new InvalidOperationException("Item " + ID + " cannot be packed in an empty bin.");
-          result.Bins.Add(bp);
-        }
-      }
-      result.UpdateBinPackings();
-      return result;
-    }
-
-    public static IList<Tuple<BinPacking3D, PackingPosition, int>> GetResidualSpaceAllPoints(Solution solution, PackingItem item) {
-      var result = new List<Tuple<BinPacking3D, PackingPosition, int>>();
-      foreach (BinPacking3D bp in solution.Bins) {
-        foreach (var ep in bp.ExtremePoints) {
-          var rs = bp.ResidualSpace[ep];
-          if (rs.Item1 < item.Width || rs.Item2 < item.Height || rs.Item3 < item.Depth) continue;
-          result.Add(Tuple.Create(bp, ep, GetResidualMerit(rs, item, ep)));
-        }
-      }
-      return result;
-    }
-
-    private static int GetResidualMerit(Tuple<int, int, int> rs, PackingItem item, PackingPosition ep) {
-      return ((rs.Item1 - item.Width) +
-          (rs.Item2 - item.Height) +
-          (rs.Item3 - item.Depth));
-    }
-  }
-}
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 15463)
@@ -0,0 +1,123 @@
+﻿using HeuristicLab.Encodings.PermutationEncoding;
+using HeuristicLab.Problems.BinPacking2D;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Problems.BinPacking3D.Sorting {
+  public static class PackingItemSorter {
+    public static Permutation SortByVolumeHeight(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)
+                         .ThenByDescending(x => x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByHeightVolume(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Height)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByAreaHeight(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Depth * x.Item.Width)
+                         .ThenByDescending(x => x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByHeightArea(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Height)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {
+      double clusterRange = bin.Width * bin.Depth * delta;
+      return new Permutation(PermutationTypes.Absolute,
+                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());
+    }
+
+    public static Permutation SortByClusteredHeightArea(this IList<PackingItem> items, PackingShape bin, double delta) {
+      double clusterRange2 = bin.Height * delta;
+      return new Permutation(PermutationTypes.Absolute,
+                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() })
+                    .OrderByDescending(x => x.Cluster)
+                    .SelectMany(x => x.Items)
+                    .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByMaterialVolumeHeight(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Material)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)
+                         .ThenByDescending(x => x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByMaterialHeightVolume(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Material)
+                         .ThenByDescending(x => x.Item.Height)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width * x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByMaterialAreaHeight(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Material)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width)
+                         .ThenByDescending(x => x.Item.Height)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByMaterialHeightArea(this IList<PackingItem> items) {
+      return new Permutation(PermutationTypes.Absolute,
+                    items.Select((v, i) => new { Index = i, Item = v })
+                         .OrderByDescending(x => x.Item.Material)
+                         .ThenByDescending(x => x.Item.Height)
+                         .ThenByDescending(x => x.Item.Depth * x.Item.Width)
+                         .Select(x => x.Index).ToArray());
+    }
+
+    public static Permutation SortByMaterialClusteredAreaHeight(this IList<PackingItem> items, PackingShape bin, double delta) {
+      double clusterRange = bin.Width * bin.Depth * delta;
+      return new Permutation(PermutationTypes.Absolute,
+                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());
+    }
+
+    public static Permutation SortByMaterialClusteredHeightArea(this IList<PackingItem> items, PackingShape bin,  double delta) {
+      double clusterRange2 = bin.Height * delta;
+      return new Permutation(PermutationTypes.Absolute,
+                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() })
+                    .OrderByDescending(x => x.Cluster)
+                    .SelectMany(x => x.Items)
+                    .Select(x => x.Index).ToArray());
+    }
+  }
+}
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)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/AlgorithmTest.cs	(revision 15463)
@@ -0,0 +1,267 @@
+﻿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 15463)
@@ -0,0 +1,63 @@
+﻿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;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Tests {
+  [TestClass]
+  public class ExtremePointAlgorithmTest {
+
+    private PackingShape _packingShape1;
+    private PackingShape _packingShape2;
+    private IList<PackingItem> _items;
+    private ExtremePointAlgorithm _extremPointAlgorithm;
+
+    [TestInitialize]
+    public void Initializes() {
+      _packingShape1 = new PackingShape(19, 19, 19);
+      _packingShape2 = new PackingShape(18, 18, 18);
+      _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 TestMethod1() {
+      object[] parameters = new object[] { _packingShape1, _items, new SortingMethod[] { SortingMethod.Given }, new FittingMethod[] { FittingMethod.FirstFit }, new CancellationToken()};
+      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;
+
+      var s = 1;
+    }
+  }
+}
Index: /branches/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 15463)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/3D/PermutationSortingTest.cs	(revision 15463)
@@ -0,0 +1,184 @@
+﻿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[] { 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 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/AlgorithmTest.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/AlgorithmTest.cs	(revision 15462)
+++ 	(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.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")]
-    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")]
-    public void TestExtremePointAlgorithmClass1() {
-      TestExtremePointAlgorithm(new RandomInstanceClass1Provider(), 1);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass2() {
-      TestExtremePointAlgorithm(new RandomInstanceClass2Provider(), 2);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass3() {
-      TestExtremePointAlgorithm(new RandomInstanceClass3Provider(), 3);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass4() {
-      TestExtremePointAlgorithm(new RandomInstanceClass4Provider(), 4);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass5() {
-      TestExtremePointAlgorithm(new RandomInstanceClass5Provider(), 5);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass6() {
-      TestExtremePointAlgorithm(new RandomInstanceClass6Provider(), 6);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    public void TestExtremePointAlgorithmClass7() {
-      TestExtremePointAlgorithm(new RandomInstanceClass7Provider(), 7);
-    }
-
-    [TestMethod]
-    [TestCategory("Problems.BinPacking")]
-    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, 10.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/Utils/TestUtils.cs
===================================================================
--- /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/Utils/TestUtils.cs	(revision 15463)
+++ /branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/Utils/TestUtils.cs	(revision 15463)
@@ -0,0 +1,20 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Problems.BinPacking._3D.Utils.Tests {
+  internal static class TestUtils {
+    public static object InvokeStaticMethod(Type type, string methodName, object[] parameters) {
+      var method = type.GetMethod(methodName, System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static);
+      return method.Invoke(null, parameters);
+    }
+
+    public static object InvokeMethod(Type type, object o, string methodName, object[] parameters) {
+      var method = type.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
+      return method.Invoke(o, parameters);
+    }
+  }
+}
