Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/AlgorithmBehaviorUnitTests.csproj	(revision 9945)
@@ -58,4 +58,8 @@
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
   </ItemGroup>
   <Choose>
@@ -75,4 +79,5 @@
     <Compile Include="UnitTest1.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ConvexHullTest.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -84,4 +89,8 @@
       <Project>{2533d1f9-f7f6-46cb-90d2-76d254e38dee}</Project>
       <Name>HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\MIConvexHull\MIConvexHull.csproj">
+      <Project>{2337776d-7d0c-40aa-a439-c26c3ce24fab}</Project>
+      <Name>MIConvexHull</Name>
     </ProjectReference>
   </ItemGroup>
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/AlgorithmBehaviorUnitTests/ConvexHullTest.cs	(revision 9945)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Diagnostics;
+using System.Linq;
+using HeuristicLab.Analysis.AlgorithmBehavior.Analyzers;
+using MIConvexHull;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace Visualization {
+  [TestClass]
+  public class ConvexHullTest {
+    [TestMethod]
+    public void TestMethod1() {
+      int nrOfSamples = 50;
+      int sampleSize = 120;
+      double[][] inputs = CreateRandomData(nrOfSamples, sampleSize);
+      var convAlgData = ConvertPermutationToVertex(inputs);
+
+      Stopwatch watch = new Stopwatch();
+      watch.Start();
+      var result2 = HyperHull.CalculateUsingSMO(inputs);
+      watch.Stop();
+      Console.WriteLine("HyperHull: " + watch.ElapsedMilliseconds);
+      watch.Restart();
+      var result1 = ConvexHull.Create(convAlgData).Points.Select(x => x.Position).ToList();
+      watch.Stop();
+      Console.WriteLine("MIConvexHull: " + watch.ElapsedMilliseconds);
+
+      int k = 0;
+      foreach (var d in result1) {
+        bool found = false;
+        foreach (var e in result2) {
+          int i = 0;
+          for (i = 0; i < e.Count(); i++) {
+            if (d[i] != e[i]) {
+              break;
+            }
+          }
+          if (i == e.Count()) {
+            found = true;
+            k++;
+            break;
+          }
+        }
+        Assert.IsTrue(found);
+      }
+      Console.WriteLine("Ratio: " + k + "/" + result1.Count);
+      Assert.AreEqual(k, result1.Count);
+    }
+
+    private List<DefaultVertex> ConvertPermutationToVertex(double[][] data) {
+      List<DefaultVertex> result = new List<DefaultVertex>();
+      for (int i = 0; i < data.Count(); i++) {
+        double[] d = data[i];
+        for (int j = 0; j < d.Length; j++) {
+          DefaultVertex vertex = new DefaultVertex();
+          vertex.Position = d.Select(x => x).ToArray();
+          result.Add(vertex);
+        }
+      }
+      return result;
+    }
+
+    private double[][] CreateRandomData(int n, int m) {
+      double[][] result = new double[n][];
+      Random rand = new Random();
+
+      for (int i = 0; i < n; i++) {
+        result[i] = new double[m];
+        for (int j = 0; j < m; j++) {
+          result[i][j] = (double)rand.Next(1, 60);
+        }
+      }
+      return result;
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/ConvexHullView.cs	(revision 9945)
@@ -50,5 +50,10 @@
       var sols = Content.GetSolutionsFromGeneration(1);
       var input = sols.Select(x => ConvertPermutationToVertex(x.GetPermutation()));
-      var result = ConvexHull.Create(input);
+      //TODO: HyperHull.Calculate(Content);
+      //HyperHull.CalculateUsingSMO(Content.GetSolutionsFromGeneration(1));
+
+
+      //var result = ConvexHull.Create(input);
+
       //TODO
     }
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views-3.3.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views-3.3.csproj	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers.Views-3.3.csproj	(revision 9945)
@@ -104,4 +104,9 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj	(revision 9945)
@@ -38,5 +38,7 @@
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
       <Private>False</Private>
     </Reference>
@@ -90,4 +92,14 @@
       <Private>False</Private>
     </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
@@ -113,4 +125,5 @@
     <Compile Include="CombinedOperators\QAPAfterMutationCombinedOperator.cs" />
     <Compile Include="CombinedOperators\QAPAfterCrossoverCombinedOperator.cs" />
+    <Compile Include="HyperHull.cs" />
     <Compile Include="SolutionsCaching\AfterCrossoverSolutionCachingAnalyzer.cs" />
     <Compile Include="SolutionsCaching\SolutionCachingAnalyzer.cs" />
@@ -121,4 +134,5 @@
     <Compile Include="SelectionPressureAnalyzer.cs" />
     <Compile Include="SolutionsCaching\PermutationInformation.cs" />
+    <Compile Include="SVM.cs" />
     <Compile Include="WorstQualityAnalyzer.cs" />
     <Compile Include="InitializableOperator.cs" />
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HyperHull.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HyperHull.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HyperHull.cs	(revision 9945)
@@ -0,0 +1,70 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
+  /// <summary>
+  /// Based on the idea from: 
+  /// http://stackoverflow.com/questions/4901959/find-if-a-point-is-inside-a-convex-hull-for-a-set-of-points-without-computing-th
+  /// </summary>
+  public class HyperHull {
+    public static List<double[]> CalculateUsingSMO(double[][] inputs) {
+      int[] labels = new int[inputs.Count()];
+      List<double[]> result = new List<double[]>();
+
+      for (int i = 0; i < inputs.Length; i++) {
+        labels[i] = -1;
+      }
+      labels[0] = 1;
+
+      for (int i = 0; i < labels.Count(); i++) {
+        if (i > 0) {
+          labels[i - 1] = -1;
+          labels[i] = 1;
+        }
+
+        KernelSupportVectorMachine machine = new KernelSupportVectorMachine(new LinearKernel(), inputs[0].Length);
+        SequentialMinimalOptimization smo = new SequentialMinimalOptimization(machine, inputs, labels);
+        smo.Complexity = 1.0;
+        smo.Epsilon = 0.0000000000001;
+        //smo.Tolerance = 0.0001;
+
+        double error = smo.Run();
+
+        bool isConvexHullPoint = true;
+        for (int j = 0; j < inputs.Length; j++) {
+          int decision = System.Math.Sign(machine.Compute(inputs[j]));
+          if (decision != labels[j]) {
+            isConvexHullPoint = false;
+            break;
+          }
+        }
+        if (isConvexHullPoint) {
+          result.Add(inputs[i]);
+        }
+      }
+      return result;
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SVM.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SVM.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/SVM.cs	(revision 9945)
@@ -0,0 +1,819 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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/>.
+ * 
+ * 
+ * Source based on 
+ * http://crsouza.blogspot.co.at/2010/04/kernel-support-vector-machines-for.html, 
+ * licensed under GNU GPL 
+ * 
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers {
+  public interface IKernel {
+    double Function(double[] x, double[] y);
+  }
+
+  public class LinearKernel : IKernel {
+    public double Function(double[] x, double[] y) {
+      double sum = 0.0;
+      for (int i = 0; i < x.Length; i++) {
+        sum += x[i] * y[i];
+      }
+      return sum;
+    }
+  }
+
+  /// <summary>
+  ///   Sparse Linear Support Vector Machine (SVM)
+  /// </summary>
+  public class SupportVectorMachine {
+
+    private int inputCount;
+    private double[][] supportVectors;
+    private double[] weights;
+    private double threshold;
+
+    /// <summary>
+    ///   Creates a new Support Vector Machine
+    /// </summary>
+    public SupportVectorMachine(int inputs) {
+      this.inputCount = inputs;
+    }
+
+    /// <summary>
+    ///   Gets the number of inputs accepted by this SVM.
+    /// </summary>
+    public int Inputs {
+      get { return inputCount; }
+    }
+
+    /// <summary>
+    ///   Gets or sets the collection of support vectors used by this machine.
+    /// </summary>
+    public double[][] SupportVectors {
+      get { return supportVectors; }
+      set { supportVectors = value; }
+    }
+
+    /// <summary>
+    ///   Gets or sets the collection of weights used by this machine.
+    /// </summary>
+    public double[] Weights {
+      get { return weights; }
+      set { weights = value; }
+    }
+
+    /// <summary>
+    ///   Gets or sets the threshold (bias) term for this machine.
+    /// </summary>
+    public double Threshold {
+      get { return threshold; }
+      set { threshold = value; }
+    }
+
+    /// <summary>
+    ///   Computes the given input to produce the corresponding output.
+    /// </summary>
+    /// <param name="input">An input vector.</param>
+    /// <returns>The ouput for the given input.</returns>
+    public virtual double Compute(double[] input) {
+      double s = threshold;
+      for (int i = 0; i < supportVectors.Length; i++) {
+        double p = 0;
+        for (int j = 0; j < input.Length; j++)
+          p += supportVectors[i][j] * input[j];
+
+        s += weights[i] * p;
+      }
+
+      return s;
+    }
+
+    /// <summary>
+    ///   Computes the given inputs to produce the corresponding outputs.
+    /// </summary>
+    public double[] Compute(double[][] inputs) {
+      double[] outputs = new double[inputs.Length];
+
+      for (int i = 0; i < inputs.Length; i++)
+        outputs[i] = Compute(inputs[i]);
+
+      return outputs;
+    }
+
+  }
+
+
+  /// <summary>
+  ///  Sparse Kernel Support Vector Machine (kSVM)
+  /// </summary>
+  /// <remarks>
+  /// <para>
+  ///   The original optimal hyperplane algorithm (SVM) proposed by Vladimir Vapnik in 1963 was a
+  ///   linear classifier. However, in 1992, Bernhard Boser, Isabelle Guyon and Vapnik suggested
+  ///   a way to create non-linear classifiers by applying the kernel trick (originally proposed
+  ///   by Aizerman et al.) to maximum-margin hyperplanes. The resulting algorithm is formally
+  ///   similar, except that every dot product is replaced by a non-linear kernel function.</para>
+  /// <para>
+  ///   This allows the algorithm to fit the maximum-margin hyperplane in a transformed feature space.
+  ///   The transformation may be non-linear and the transformed space high dimensional; thus though
+  ///   the classifier is a hyperplane in the high-dimensional feature space, it may be non-linear in
+  ///   the original input space.</para> 
+  /// <para>
+  ///   References:
+  ///   <list type="bullet">
+  ///     <item><description><a href="http://en.wikipedia.org/wiki/Support_vector_machine">
+  ///       http://en.wikipedia.org/wiki/Support_vector_machine</a></description></item>
+  ///     <item><description><a href="http://www.kernel-machines.org/">
+  ///       http://www.kernel-machines.org/</a></description></item>
+  ///   </list></para>  
+  /// </remarks>
+  /// 
+  /// <example>
+  ///   <code>
+  ///   // Example XOR problem
+  ///   double[][] inputs =
+  ///   {
+  ///       new double[] { 0, 0 }, // 0 xor 0: 1 (label +1)
+  ///       new double[] { 0, 1 }, // 0 xor 1: 0 (label -1)
+  ///       new double[] { 1, 0 }, // 1 xor 0: 0 (label -1)
+  ///       new double[] { 1, 1 }  // 1 xor 1: 1 (label +1)
+  ///   };
+  ///   
+  ///   // Dichotomy SVM outputs should be given as [-1;+1]
+  ///   int[] labels =
+  ///   {
+  ///       // 1,  0,  0, 1
+  ///          1, -1, -1, 1
+  ///   };
+  ///   
+  ///   // Create a Kernel Support Vector Machine for the given inputs
+  ///   KernelSupportVectorMachine machine = new KernelSupportVectorMachine(new Gaussian(0.1), inputs[0].Length);
+  ///   
+  ///   // Instantiate a new learning algorithm for SVMs
+  ///   SequentialMinimalOptimization smo = new SequentialMinimalOptimization(machine, inputs, labels);
+  ///   
+  ///   // Set up the learning algorithm
+  ///   smo.Complexity = 1.0;
+  ///   
+  ///   // Run the learning algorithm
+  ///   double error = smo.Run();
+  ///   
+  ///   // Compute the decision output for one of the input vectors
+  ///   int decision = System.Math.Sign(svm.Compute(inputs[0]));
+  ///   </code>
+  /// </example>
+  /// 
+  public class KernelSupportVectorMachine : SupportVectorMachine {
+
+    private IKernel kernel;
+
+
+    /// <summary>
+    ///   Creates a new Kernel Support Vector Machine.
+    /// </summary>
+    /// 
+    /// <param name="kernel">The chosen kernel for the machine.</param>
+    /// <param name="inputs">The number of inputs for the machine.</param>
+    /// 
+    /// <remarks>
+    ///   If the number of inputs is zero, this means the machine
+    ///   accepts a indefinite number of inputs. This is often the
+    ///   case for kernel vector machines using a sequence kernel.
+    /// </remarks>
+    /// 
+    public KernelSupportVectorMachine(IKernel kernel, int inputs)
+      : base(inputs) {
+      if (kernel == null) throw new ArgumentNullException("kernel");
+
+      this.kernel = kernel;
+    }
+
+    /// <summary>
+    ///   Gets or sets the kernel used by this machine.
+    /// </summary>
+    /// 
+    public IKernel Kernel {
+      get { return kernel; }
+      set { kernel = value; }
+    }
+
+    /// <summary>
+    ///   Computes the given input to produce the corresponding output.
+    /// </summary>
+    /// 
+    /// <remarks>
+    ///   For a binary decision problem, the decision for the negative
+    ///   or positive class is typically computed by taking the sign of
+    ///   the machine's output.
+    /// </remarks>
+    /// 
+    /// <param name="inputs">An input vector.</param>
+    /// <returns>The output for the given input.</returns>
+    /// 
+    public override double Compute(double[] inputs) {
+      double s = Threshold;
+
+      for (int i = 0; i < SupportVectors.Length; i++)
+        s += Weights[i] * kernel.Function(SupportVectors[i], inputs);
+
+      return s;
+    }
+  }
+
+
+
+
+
+
+
+
+
+
+
+
+  /// <summary>
+  ///   Sequential Minimal Optimization (SMO) Algorithm
+  /// </summary>
+  /// 
+  /// <remarks>
+  /// <para>
+  ///   The SMO algorithm is an algorithm for solving large quadratic programming (QP)
+  ///   optimization problems, widely used for the training of support vector machines.
+  ///   First developed by John C. Platt in 1998, SMO breaks up large QP problems into
+  ///   a series of smallest possible QP problems, which are then solved analytically.</para>
+  /// <para>
+  ///   This class follows the original algorithm by Platt as strictly as possible.</para>
+  ///  
+  /// <para>
+  ///   References:
+  ///   <list type="bullet">
+  ///     <item><description>
+  ///       <a href="http://en.wikipedia.org/wiki/Sequential_Minimal_Optimization">
+  ///       Wikipedia, The Free Encyclopedia. Sequential Minimal Optimization. Available on:
+  ///       http://en.wikipedia.org/wiki/Sequential_Minimal_Optimization </a></description></item>
+  ///     <item><description>
+  ///       <a href="http://research.microsoft.com/en-us/um/people/jplatt/smoTR.pdf">
+  ///       John C. Platt, Sequential Minimal Optimization: A Fast Algorithm for Training Support
+  ///       Vector Machines. 1998. Available on: http://research.microsoft.com/en-us/um/people/jplatt/smoTR.pdf </a></description></item>
+  ///     <item><description>
+  ///       <a href="http://www.idiom.com/~zilla/Work/Notes/svmtutorial.pdf">
+  ///       J. P. Lewis. A Short SVM (Support Vector Machine) Tutorial. Available on:
+  ///       http://www.idiom.com/~zilla/Work/Notes/svmtutorial.pdf </a></description></item>
+  ///     </list></para>  
+  /// </remarks>
+  /// 
+  /// <example>
+  ///   <code>
+  ///   // Example XOR problem
+  ///   double[][] inputs =
+  ///   {
+  ///       new double[] { 0, 0 }, // 0 xor 0: 1 (label +1)
+  ///       new double[] { 0, 1 }, // 0 xor 1: 0 (label -1)
+  ///       new double[] { 1, 0 }, // 1 xor 0: 0 (label -1)
+  ///       new double[] { 1, 1 }  // 1 xor 1: 1 (label +1)
+  ///   };
+  ///    
+  ///   // Dichotomy SVM outputs should be given as [-1;+1]
+  ///   int[] labels =
+  ///   {
+  ///          1, -1, -1, 1
+  ///   };
+  ///  
+  ///   // Create a Kernel Support Vector Machine for the given inputs
+  ///   KernelSupportVectorMachine machine = new KernelSupportVectorMachine(new Gaussian(0.1), inputs[0].Length);
+  /// 
+  ///   // Instantiate a new learning algorithm for SVMs
+  ///   SequentialMinimalOptimization smo = new SequentialMinimalOptimization(machine, inputs, labels);
+  /// 
+  ///   // Set up the learning algorithm
+  ///   smo.Complexity = 1.0;
+  /// 
+  ///   // Run the learning algorithm
+  ///   double error = smo.Run();
+  ///   
+  ///   // Compute the decision output for one of the input vectors
+  ///   int decision = System.Math.Sign(svm.Compute(inputs[0]));
+  ///  </code>
+  /// </example>
+  /// 
+  public class SequentialMinimalOptimization {
+    private static Random random = new Random();
+
+    // Training data
+    private double[][] inputs;
+    private int[] outputs;
+
+    // Learning algorithm parameters
+    private double c = 1.0;
+    private double tolerance = 1e-3;
+    private double epsilon = 1e-3;
+    private bool useComplexityHeuristic;
+
+    // Support Vector Machine parameters
+    private SupportVectorMachine machine;
+    private IKernel kernel;
+    private double[] alpha;
+    private double bias;
+
+
+    // Error cache to speed up computations
+    private double[] errors;
+
+
+    /// <summary>
+    ///   Initializes a new instance of a Sequential Minimal Optimization (SMO) algorithm.
+    /// </summary>
+    /// 
+    /// <param name="machine">A Support Vector Machine.</param>
+    /// <param name="inputs">The input data points as row vectors.</param>
+    /// <param name="outputs">The classification label for each data point in the range [-1;+1].</param>
+    /// 
+    public SequentialMinimalOptimization(SupportVectorMachine machine,
+      double[][] inputs, int[] outputs) {
+
+      // Initial argument checking
+      if (machine == null)
+        throw new ArgumentNullException("machine");
+
+      if (inputs == null)
+        throw new ArgumentNullException("inputs");
+
+      if (outputs == null)
+        throw new ArgumentNullException("outputs");
+
+      if (inputs.Length != outputs.Length)
+        throw new ArgumentException("The number of inputs and outputs does not match.", "outputs");
+
+      for (int i = 0; i < outputs.Length; i++) {
+        if (outputs[i] != 1 && outputs[i] != -1)
+          throw new ArgumentOutOfRangeException("outputs", "One of the labels in the output vector is neither +1 or -1.");
+      }
+
+      if (machine.Inputs > 0) {
+        // This machine has a fixed input vector size
+        for (int i = 0; i < inputs.Length; i++)
+          if (inputs[i].Length != machine.Inputs)
+            throw new ArgumentException(
+              "The size of the input vectors does not match the expected number of inputs of the machine");
+      }
+
+
+      // Machine
+      this.machine = machine;
+
+      // Kernel (if applicable)
+      KernelSupportVectorMachine ksvm = machine as KernelSupportVectorMachine;
+      this.kernel = (ksvm != null) ? ksvm.Kernel : new LinearKernel();
+
+
+      // Learning data
+      this.inputs = inputs;
+      this.outputs = outputs;
+
+    }
+
+
+    //---------------------------------------------
+
+
+    #region Properties
+
+    /// <summary>
+    ///   Complexity (cost) parameter C. Increasing the value of C forces the creation
+    ///   of a more accurate model that may not generalize well. Default value is the
+    ///   number of examples divided by the trace of the kernel matrix.
+    /// </summary>
+    /// <remarks>
+    ///   The cost parameter C controls the trade off between allowing training
+    ///   errors and forcing rigid margins. It creates a soft margin that permits
+    ///   some misclassifications. Increasing the value of C increases the cost of
+    ///   misclassifying points and forces the creation of a more accurate model
+    ///   that may not generalize well.
+    /// </remarks>
+    public double Complexity {
+      get { return this.c; }
+      set { this.c = value; }
+    }
+
+
+    /// <summary>
+    ///   Gets or sets a value indicating whether the Complexity parameter C
+    ///   should be computed automatically by employing an heuristic rule.
+    /// </summary>
+    /// <value>
+    ///     <c>true</c> if complexity should be computed automatically; otherwise, <c>false</c>.
+    /// </value>
+    public bool UseComplexityHeuristic {
+      get { return useComplexityHeuristic; }
+      set { useComplexityHeuristic = value; }
+    }
+
+    /// <summary>
+    ///   Insensitivity zone ε. Increasing the value of ε can result in fewer support
+    ///   vectors in the created model. Default value is 1e-3.
+    /// </summary>
+    /// <remarks>
+    ///   Parameter ε controls the width of the ε-insensitive zone, used to fit the training
+    ///   data. The value of ε can affect the number of support vectors used to construct the
+    ///   regression function. The bigger ε, the fewer support vectors are selected. On the
+    ///   other hand, bigger ε-values results in more flat estimates.
+    /// </remarks>
+    public double Epsilon {
+      get { return epsilon; }
+      set { epsilon = value; }
+    }
+
+    /// <summary>
+    ///   Convergence tolerance. Default value is 1e-3.
+    /// </summary>
+    /// <remarks>
+    ///   The criterion for completing the model training process. The default is 0.001.
+    /// </remarks>
+    public double Tolerance {
+      get { return this.tolerance; }
+      set { this.tolerance = value; }
+    }
+
+    #endregion
+
+
+    //---------------------------------------------
+
+
+    /// <summary>
+    ///   Runs the SMO algorithm.
+    /// </summary>
+    /// 
+    /// <param name="computeError">
+    ///   True to Compute error after the training
+    ///   process completes, false otherwise. Default is true.
+    /// </param>
+    /// 
+    /// <returns>
+    ///   The misclassification error rate of
+    ///   the resulting support vector machine.
+    /// </returns>
+    /// 
+    public double Run(bool computeError) {
+
+      // The SMO algorithm chooses to solve the smallest possible optimization problem
+      // at every step. At every step, SMO chooses two Lagrange multipliers to jointly
+      // optimize, finds the optimal values for these multipliers, and updates the SVM
+      // to reflect the new optimal values
+      //
+      // Reference: http://research.microsoft.com/en-us/um/people/jplatt/smoTR.pdf
+
+
+      // Initialize variables
+      int N = inputs.Length;
+
+      if (useComplexityHeuristic)
+        c = ComputeComplexity();
+
+      // Lagrange multipliers
+      this.alpha = new double[N];
+
+      // Error cache
+      this.errors = new double[N];
+
+      // Algorithm:
+      int numChanged = 0;
+      int examineAll = 1;
+
+      while (numChanged > 0 || examineAll > 0) {
+        numChanged = 0;
+        if (examineAll > 0) {
+          // loop I over all training examples
+          for (int i = 0; i < N; i++)
+            numChanged += examineExample(i);
+        } else {
+          // loop I over examples where alpha is not 0 and not C
+          for (int i = 0; i < N; i++)
+            if (alpha[i] != 0 && alpha[i] != c)
+              numChanged += examineExample(i);
+        }
+
+        if (examineAll == 1)
+          examineAll = 0;
+        else if (numChanged == 0)
+          examineAll = 1;
+      }
+
+
+      // Store Support Vectors in the SV Machine. Only vectors which have lagrange multipliers
+      // greater than zero will be stored as only those are actually required during evaluation.
+      List<int> indices = new List<int>();
+      for (int i = 0; i < N; i++) {
+        // Only store vectors with multipliers > 0
+        if (alpha[i] > 0) indices.Add(i);
+      }
+
+      int vectors = indices.Count;
+      machine.SupportVectors = new double[vectors][];
+      machine.Weights = new double[vectors];
+      for (int i = 0; i < vectors; i++) {
+        int j = indices[i];
+        machine.SupportVectors[i] = inputs[j];
+        machine.Weights[i] = alpha[j] * outputs[j];
+      }
+      machine.Threshold = -bias;
+
+
+      // Compute error if required.
+      return (computeError) ? ComputeError(inputs, outputs) : 0.0;
+    }
+
+    /// <summary>
+    ///   Runs the SMO algorithm.
+    /// </summary>
+    /// 
+    /// <returns>
+    ///   The misclassification error rate of
+    ///   the resulting support vector machine.
+    /// </returns>
+    /// 
+    public double Run() {
+      return Run(true);
+    }
+
+    /// <summary>
+    ///   Computes the error rate for a given set of input and outputs.
+    /// </summary>
+    /// 
+    public double ComputeError(double[][] inputs, int[] expectedOutputs) {
+      // Compute errors
+      int count = 0;
+      for (int i = 0; i < inputs.Length; i++) {
+        if (Math.Sign(Compute(inputs[i])) != Math.Sign(expectedOutputs[i]))
+          count++;
+      }
+
+      // Return misclassification error ratio
+      return (double)count / inputs.Length;
+    }
+
+    //---------------------------------------------
+
+
+    /// <summary>
+    ///  Chooses which multipliers to optimize using heuristics.
+    /// </summary>
+    /// 
+    private int examineExample(int i2) {
+      double[] p2 = inputs[i2]; // Input point at index i2
+      double y2 = outputs[i2]; // Classification label for p2
+      double alph2 = alpha[i2]; // Lagrange multiplier for p2
+
+      // SVM output on p2 - y2. Check if it has already been computed
+      double e2 = (alph2 > 0 && alph2 < c) ? errors[i2] : Compute(p2) - y2;
+
+      double r2 = y2 * e2;
+
+
+      // Heuristic 01 (for the first multiplier choice):
+      //  - Testing for KKT conditions within the tolerance margin
+      if (!(r2 < -tolerance && alph2 < c) && !(r2 > tolerance && alph2 > 0))
+        return 0;
+
+
+      // Heuristic 02 (for the second multiplier choice):
+      //  - Once a first Lagrange multiplier is chosen, SMO chooses the second Lagrange multiplier to
+      //    maximize the size of the step taken during joint optimization. Now, evaluating the kernel
+      //    function is time consuming, so SMO approximates the step size by the absolute value of the
+      //    absolute error difference.
+      int i1 = -1;
+      double max = 0;
+      for (int i = 0; i < inputs.Length; i++) {
+        if (alpha[i] > 0 && alpha[i] < c) {
+          double error1 = errors[i];
+          double aux = System.Math.Abs(e2 - error1);
+
+          if (aux > max) {
+            max = aux;
+            i1 = i;
+          }
+        }
+      }
+
+      if (i1 >= 0 && takeStep(i1, i2)) return 1;
+
+
+      // Heuristic 03:
+      //  - Under unusual circumstances, SMO cannot make positive progress using the second
+      //    choice heuristic above. If it is the case, then SMO starts iterating through the
+      //    non-bound examples, searching for an second example that can make positive progress.
+
+      int start = random.Next(inputs.Length);
+      for (i1 = start; i1 < inputs.Length; i1++) {
+        if (alpha[i1] > 0 && alpha[i1] < c)
+          if (takeStep(i1, i2)) return 1;
+      }
+      for (i1 = 0; i1 < start; i1++) {
+        if (alpha[i1] > 0 && alpha[i1] < c)
+          if (takeStep(i1, i2)) return 1;
+      }
+
+
+      // Heuristic 04:
+      //  - If none of the non-bound examples make positive progress, then SMO starts iterating
+      //    through the entire training set until an example is found that makes positive progress.
+      //    Both the iteration through the non-bound examples and the iteration through the entire
+      //    training set are started at random locations, in order not to bias SMO towards the
+      //    examples at the beginning of the training set. 
+
+      start = random.Next(inputs.Length);
+      for (i1 = start; i1 < inputs.Length; i1++) {
+        if (takeStep(i1, i2)) return 1;
+      }
+      for (i1 = 0; i1 < start; i1++) {
+        if (takeStep(i1, i2)) return 1;
+      }
+
+
+      // In extremely degenerate circumstances, none of the examples will make an adequate second
+      // example. When this happens, the first example is skipped and SMO continues with another
+      // chosen first example.
+      return 0;
+    }
+
+    /// <summary>
+    ///   Analytically solves the optimization problem for two Lagrange multipliers.
+    /// </summary>
+    /// 
+    private bool takeStep(int i1, int i2) {
+      if (i1 == i2) return false;
+
+      double[] p1 = inputs[i1]; // Input point at index i1
+      double alph1 = alpha[i1]; // Lagrange multiplier for p1
+      double y1 = outputs[i1]; // Classification label for p1
+
+      // SVM output on p1 - y1. Check if it has already been computed
+      double e1 = (alph1 > 0 && alph1 < c) ? errors[i1] : Compute(p1) - y1;
+
+      double[] p2 = inputs[i2]; // Input point at index i2
+      double alph2 = alpha[i2]; // Lagrange multiplier for p2
+      double y2 = outputs[i2]; // Classification label for p2
+
+      // SVM output on p2 - y2. Check if it has already been computed
+      double e2 = (alph2 > 0 && alph2 < c) ? errors[i2] : Compute(p2) - y2;
+
+
+      double s = y1 * y2;
+
+
+      // Compute L and H according to equations (13) and (14) (Platt, 1998)
+      double L, H;
+      if (y1 != y2) {
+        // If the target y1 does not equal the target           (13)
+        // y2, then the following bounds apply to a2:
+        L = Math.Max(0, alph2 - alph1);
+        H = Math.Min(c, c + alph2 - alph1);
+      } else {
+        // If the target y1 does equal the target               (14)
+        // y2, then the following bounds apply to a2:
+        L = Math.Max(0, alph2 + alph1 - c);
+        H = Math.Min(c, alph2 + alph1);
+      }
+
+      if (L == H) return false;
+
+      double k11, k22, k12, eta;
+      k11 = kernel.Function(p1, p1);
+      k12 = kernel.Function(p1, p2);
+      k22 = kernel.Function(p2, p2);
+      eta = k11 + k22 - 2.0 * k12;
+
+      double a1, a2;
+
+      if (eta > 0) {
+        a2 = alph2 - y2 * (e2 - e1) / eta;
+
+        if (a2 < L) a2 = L;
+        else if (a2 > H) a2 = H;
+      } else {
+        // Compute objective function Lobj and Hobj at
+        //  a2=L and a2=H respectively, using (eq. 19)
+
+        double L1 = alph1 + s * (alph2 - L);
+        double H1 = alph1 + s * (alph2 - H);
+        double f1 = y1 * (e1 + bias) - alph1 * k11 - s * alph2 * k12;
+        double f2 = y2 * (e2 + bias) - alph2 * k22 - s * alph1 * k12;
+        double Lobj = -0.5 * L1 * L1 * k11 - 0.5 * L * L * k22 - s * L * L1 * k12 - L1 * f1 - L * f2;
+        double Hobj = -0.5 * H1 * H1 * k11 - 0.5 * H * H * k22 - s * H * H1 * k12 - H1 * f1 - H * f2;
+
+        if (Lobj > Hobj + epsilon) a2 = L;
+        else if (Lobj < Hobj - epsilon) a2 = H;
+        else a2 = alph2;
+      }
+
+      if (Math.Abs(a2 - alph2) < epsilon * (a2 + alph2 + epsilon))
+        return false;
+
+      a1 = alph1 + s * (alph2 - a2);
+
+      if (a1 < 0) {
+        a2 += s * a1;
+        a1 = 0;
+      } else if (a1 > c) {
+        double d = a1 - c;
+        a2 += s * d;
+        a1 = c;
+      }
+
+
+      // Update threshold (bias) to reflect change in Lagrange multipliers
+      double b1 = 0, b2 = 0;
+      double new_b = 0, delta_b;
+
+      if (a1 > 0 && a1 < c) {
+        // a1 is not at bounds
+        new_b = e1 + y1 * (a1 - alph1) * k11 + y2 * (a2 - alph2) * k12 + bias;
+      } else {
+        if (a2 > 0 && a2 < c) {
+          // a1 is at bounds but a2 is not.
+          new_b = e2 + y1 * (a1 - alph1) * k12 + y2 * (a2 - alph2) * k22 + bias;
+        } else {
+          // Both new Lagrange multipliers are at bound. SMO algorithm
+          // chooses the threshold to be halfway in between b1 and b2.
+          b1 = e1 + y1 * (a1 - alph1) * k11 + y2 * (a2 - alph2) * k12 + bias;
+          b2 = e2 + y1 * (a1 - alph1) * k12 + y2 * (a2 - alph2) * k22 + bias;
+          new_b = (b1 + b2) / 2;
+        }
+      }
+
+      delta_b = new_b - bias;
+      bias = new_b;
+
+
+      // Update error cache using new Lagrange multipliers
+      double t1 = y1 * (a1 - alph1);
+      double t2 = y2 * (a2 - alph2);
+
+      for (int i = 0; i < inputs.Length; i++) {
+        if (0 < alpha[i] && alpha[i] < c) {
+          double[] point = inputs[i];
+          errors[i] +=
+            t1 * kernel.Function(p1, point) +
+            t2 * kernel.Function(p2, point) -
+            delta_b;
+        }
+      }
+
+      errors[i1] = 0f;
+      errors[i2] = 0f;
+
+
+      // Update lagrange multipliers
+      alpha[i1] = a1;
+      alpha[i2] = a2;
+
+
+      return true;
+    }
+
+    /// <summary>
+    ///   Computes the SVM output for a given point.
+    /// </summary>
+    /// 
+    private double Compute(double[] point) {
+      double sum = -bias;
+      for (int i = 0; i < inputs.Length; i++) {
+        if (alpha[i] > 0)
+          sum += alpha[i] * outputs[i] * kernel.Function(inputs[i], point);
+      }
+
+      return sum;
+    }
+
+    private double ComputeComplexity() {
+      // Compute initial value for C as the number of examples
+      // divided by the trace of the input sample kernel matrix.
+      double sum = 0.0;
+      for (int i = 0; i < inputs.Length; i++)
+        sum += kernel.Function(inputs[i], inputs[i]);
+      return inputs.Length / sum;
+    }
+
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.sln
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.sln	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.sln	(revision 9945)
@@ -17,4 +17,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MIConvexHull", "MIConvexHull\MIConvexHull.csproj", "{2337776D-7D0C-40AA-A439-C26C3CE24FAB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Visualization", "Visualization\Visualization.csproj", "{E968DFEC-F612-4898-B92A-00A45E2DEE85}"
 EndProject
 Global
@@ -72,4 +74,12 @@
 		{2337776D-7D0C-40AA-A439-C26C3CE24FAB}.Release|x64.ActiveCfg = Release|Any CPU
 		{2337776D-7D0C-40AA-A439-C26C3CE24FAB}.Release|x86.ActiveCfg = Release|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Release|x64.ActiveCfg = Release|Any CPU
+		{E968DFEC-F612-4898-B92A-00A45E2DEE85}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/Constants.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/Constants.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/Constants.cs	(revision 9945)
@@ -0,0 +1,22 @@
+﻿
+namespace MIConvexHull
+{
+    internal static class Constants
+    {
+        internal const double epsilon = 1e-8;
+        internal const double epsilonSquared = 1e-16;
+
+
+        /// <summary>
+        /// Checks whether to points are essentially the same position.
+        /// </summary>
+        /// <param name="pt1">The PT1.</param>
+        /// <param name="pt2">The PT2.</param>
+        /// <param name="dimension">The dimension.</param>
+        /// <returns></returns>
+        public static bool SamePosition(double[] pt1, double[] pt2, int dimension)
+        {
+            return (StarMath.norm2(StarMath.subtract(pt1, pt2, dimension), dimension, true) < epsilonSquared);
+        }
+    }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexFaceInternal.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexFaceInternal.cs	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexFaceInternal.cs	(revision 9945)
@@ -40,4 +40,20 @@
             return x.Index.CompareTo(y.Index);
         }
+    }
+
+    /// <summary>
+    /// For deferred face addition.
+    /// </summary>
+    sealed class DeferredFace
+    {
+        /// <summary>
+        /// The faces.
+        /// </summary>
+        public ConvexFaceInternal Face, Pivot, OldFace;
+
+        /// <summary>
+        /// The indices.
+        /// </summary>
+        public int FaceIndex, PivotIndex;
     }
 
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexHullInternal.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexHullInternal.cs	(revision 9791)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/ConvexHullInternal.cs	(revision 9945)
@@ -42,4 +42,7 @@
         VertexBuffer BeyondBuffer;
         List<ConvexFaceInternal> AffectedFaceBuffer;
+        List<DeferredFace> ConeFaceBuffer;
+        Stack<DeferredFace> ConeFaceStack;
+        HashSet<VertexWrap> SingularVertices;
 
         const int ConnectorTableSize = 2017;
@@ -69,4 +72,7 @@
             EmptyBuffer = new VertexBuffer();
             AffectedFaceBuffer = new List<ConvexFaceInternal>();
+            ConeFaceBuffer = new List<DeferredFace>();
+            ConeFaceStack = new Stack<DeferredFace>();
+            SingularVertices = new HashSet<VertexWrap>();
             BeyondBuffer = new VertexBuffer();
 
@@ -130,5 +136,5 @@
         /// <param name="face"></param>
         /// <returns></returns>
-        private void CalculateFacePlane(ConvexFaceInternal face)
+        private bool CalculateFacePlane(ConvexFaceInternal face)
         {
             var vertices = face.Vertices;
@@ -136,5 +142,9 @@
             FindNormalVector(vertices, normal);
 
-            if (double.IsNaN(normal[0])) ThrowSingular();
+            if (double.IsNaN(normal[0]))
+            {
+                return false;
+                //ThrowSingular();
+            }
 
             double offset = 0.0;
@@ -157,4 +167,6 @@
             }
             else face.IsNormalFlipped = false;
+
+            return true;
         }
         
@@ -318,4 +330,26 @@
 
         /// <summary>
+        /// Creates a new deferred face.
+        /// </summary>
+        /// <param name="face"></param>
+        /// <param name="faceIndex"></param>
+        /// <param name="pivot"></param>
+        /// <param name="pivotIndex"></param>
+        /// <param name="oldFace"></param>
+        /// <returns></returns>
+        DeferredFace GetDeferredFace(ConvexFaceInternal face, int faceIndex, ConvexFaceInternal pivot, int pivotIndex, ConvexFaceInternal oldFace)
+        {
+            var ret = ConeFaceStack.Count > 0 ? ConeFaceStack.Pop() : new DeferredFace();
+            
+            ret.Face = face;
+            ret.FaceIndex = faceIndex;
+            ret.Pivot = pivot;
+            ret.PivotIndex = pivotIndex;
+            ret.OldFace = oldFace;
+
+            return ret;
+        }
+
+        /// <summary>
         /// Connect faces using a connector.
         /// </summary>
@@ -326,5 +360,4 @@
             var list = ConnectorTable[index];
 
-            int count = 0;
             for (var current = list.First; current != null; current = current.Next)
             {
@@ -347,13 +380,12 @@
         /// Removes the faces "covered" by the current vertex and adds the newly created ones.
         /// </summary>
-        private void CreateCone()
-        {
-            var oldFaces = AffectedFaceBuffer;
-
+        private bool CreateCone()
+        {
             var currentVertexIndex = CurrentVertex.Index;
-
-            for (int fIndex = 0; fIndex < oldFaces.Count; fIndex++)
-            {
-                var oldFace = oldFaces[fIndex];
+            ConeFaceBuffer.Clear();
+
+            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
+            {
+                var oldFace = AffectedFaceBuffer[fIndex];
 
                 // Find the faces that need to be updated
@@ -368,14 +400,4 @@
                         ++updateCount;
                     }
-                }
-
-                // Recycle the face for future use
-                if (updateCount == 0)
-                {
-                    // If the face is present in the unprocessed list, remove it 
-                    UnprocessedFaces.Remove(oldFace);
-
-                    RecycleFace(oldFace);
-                    RecycledFaceStack.Push(oldFace);
                 }
 
@@ -402,19 +424,8 @@
                     VertexWrap[] vertices;
 
-                    // Recycle the oldFace
-                    if (i == updateCount - 1)
-                    {
-                        RecycleFace(oldFace);
-                        newFace = oldFace;
-                        vertices = newFace.Vertices;
-                        oldVertexIndex = vertices[forbidden].Index;
-                    }
-                    else // Pop a face from the recycled stack or create a new one
-                    {
-                        newFace = GetNewFace();
-                        vertices = newFace.Vertices;                        
-                        for (int j = 0; j < Dimension; j++) vertices[j] = oldFace.Vertices[j];
-                        oldVertexIndex = vertices[forbidden].Index;
-                    }
+                    newFace = GetNewFace();
+                    vertices = newFace.Vertices;                        
+                    for (int j = 0; j < Dimension; j++) vertices[j] = oldFace.Vertices[j];
+                    oldVertexIndex = vertices[forbidden].Index;
 
                     int orderedPivotIndex;
@@ -450,40 +461,80 @@
                     vertices[orderedPivotIndex] = CurrentVertex;
 
-                    CalculateFacePlane(newFace);
-                    newFace.AdjacentFaces[orderedPivotIndex] = adjacentFace;
-                    adjacentFace.AdjacentFaces[oldFaceAdjacentIndex] = newFace;
-
-                    // let there be a connection.
-                    for (int j = 0; j < Dimension; j++)
+                    if (!CalculateFacePlane(newFace))
                     {
-                        if (j == orderedPivotIndex) continue;
-                        var connector = GetNewConnector();
-                        connector.Update(newFace, j, Dimension);
-                        ConnectFace(connector);
+                        return false;
                     }
-                    
-                    // This could slightly help...
-                    if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
-                    {
-                        FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
-                    }
-                    else
-                    {
-                        FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
-                    }
-
-                    // This face will definitely lie on the hull
-                    if (newFace.VerticesBeyond.Count == 0)
-                    {
-                        ConvexFaces.Add(newFace);
-                        UnprocessedFaces.Remove(newFace);
-                        EmptyBufferStack.Push(newFace.VerticesBeyond);
-                        newFace.VerticesBeyond = EmptyBuffer;
-                    }
-                    else // Add the face to the list
-                    {
-                        UnprocessedFaces.Add(newFace);
-                    }
-                }
+
+                    ConeFaceBuffer.Add(GetDeferredFace(newFace, orderedPivotIndex, adjacentFace, oldFaceAdjacentIndex, oldFace));
+                }
+            }
+            
+            return true;
+        }
+
+        /// <summary>
+        /// Commits a cone and adds a vertex to the convex hull.
+        /// </summary>
+        void CommitCone()
+        {
+            // Add the current vertex.
+            ConvexHull.Add(CurrentVertex);
+            
+            // Fill the adjacency.
+            for (int i = 0; i < ConeFaceBuffer.Count; i++)
+            {
+                var face = ConeFaceBuffer[i];
+
+                var newFace = face.Face;
+                var adjacentFace = face.Pivot;
+                var oldFace = face.OldFace;
+                var orderedPivotIndex = face.FaceIndex;
+
+                newFace.AdjacentFaces[orderedPivotIndex] = adjacentFace;
+                adjacentFace.AdjacentFaces[face.PivotIndex] = newFace;
+
+                // let there be a connection.
+                for (int j = 0; j < Dimension; j++)
+                {
+                    if (j == orderedPivotIndex) continue;
+                    var connector = GetNewConnector();
+                    connector.Update(newFace, j, Dimension);
+                    ConnectFace(connector);
+                }
+
+                // This could slightly help...
+                if (adjacentFace.VerticesBeyond.Count < oldFace.VerticesBeyond.Count)
+                {
+                    FindBeyondVertices(newFace, adjacentFace.VerticesBeyond, oldFace.VerticesBeyond);
+                }
+                else
+                {
+                    FindBeyondVertices(newFace, oldFace.VerticesBeyond, adjacentFace.VerticesBeyond);
+                }
+
+                // This face will definitely lie on the hull
+                if (newFace.VerticesBeyond.Count == 0)
+                {
+                    ConvexFaces.Add(newFace);
+                    UnprocessedFaces.Remove(newFace);
+                    EmptyBufferStack.Push(newFace.VerticesBeyond);
+                    newFace.VerticesBeyond = EmptyBuffer;
+                }
+                else // Add the face to the list
+                {
+                    UnprocessedFaces.Add(newFace);
+                }
+
+                // recycle the object.
+                ConeFaceStack.Push(face);
+            }
+
+            // Recycle the affected faces.
+            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
+            {
+                var face = AffectedFaceBuffer[fIndex];
+                UnprocessedFaces.Remove(face);
+                RecycleFace(face);
+                RecycledFaceStack.Push(face);
             }
         }
@@ -698,7 +749,19 @@
         void UpdateCenter()
         {
-            for (int i = 0; i < Dimension; i++) Center[i] *= (ConvexHull.Count - 1);
-            double f = 1.0 / ConvexHull.Count;
+            var count = ConvexHull.Count + 1;
+            for (int i = 0; i < Dimension; i++) Center[i] *= (count - 1);
+            double f = 1.0 / count;
             for (int i = 0; i < Dimension; i++) Center[i] = f * (Center[i] + CurrentVertex.PositionData[i]);
+        }
+
+        /// <summary>
+        /// Removes the last vertex from the center.
+        /// </summary>
+        void RollbackCenter()
+        {
+            var count = ConvexHull.Count + 1;
+            for (int i = 0; i < Dimension; i++) Center[i] *= count;
+            double f = 1.0 / (count - 1);
+            for (int i = 0; i < Dimension; i++) Center[i] = f * (Center[i] - CurrentVertex.PositionData[i]);
         }
 
@@ -715,6 +778,7 @@
             {
                 CurrentVertex = vertex;
+                // update center must be called before adding the vertex.
+                UpdateCenter();
                 ConvexHull.Add(CurrentVertex);
-                UpdateCenter();
                 InputVertices.Remove(vertex);
 
@@ -767,5 +831,5 @@
             for (int i = 2; i <= Dimension; i++)
             {
-                double maximum = 0.0001;
+                double maximum = 0.000001;
                 VertexWrap maxPoint = null;
                 for (int j = 0; j < extremes.Count; j++)
@@ -817,14 +881,17 @@
         double GetSimplexVolume(VertexWrap pivot, List<VertexWrap> initialPoints)
         {
-            var dim = initialPoints.Count;
-            var m = nDMatrix;
-
-            for (int i = 0; i < dim; i++)
-            {
-                var pts = initialPoints[i];
-                for (int j = 0; j < dim; j++) m[i, j] = pts.PositionData[j] - pivot.PositionData[j];
-            }
-
-            return Math.Abs(StarMath.determinantDestructive(m, dim));
+            var initPtsNum = initialPoints.Count;
+            //var m = nDMatrix;
+            var sum = 0.0;
+        
+            for (int i = 0; i < initPtsNum; i++)
+            {
+                var initPt = initialPoints[i];
+                for (int j = 0; j < Dimension; j++)
+                    sum += (initPt.PositionData[j] - pivot.PositionData[j]) 
+                        * (initPt.PositionData[j] - pivot.PositionData[j]);
+            }
+
+            return sum;
         }
 
@@ -878,4 +945,29 @@
 
         /// <summary>
+        /// Handles singular vertex.
+        /// </summary>
+        void HandleSingular()
+        {
+            RollbackCenter();
+            SingularVertices.Add(CurrentVertex);
+
+            // This means that all the affected faces must be on the hull and that all their "vertices beyond" are singular.
+            for (int fIndex = 0; fIndex < AffectedFaceBuffer.Count; fIndex++)
+            {
+                var face = AffectedFaceBuffer[fIndex];
+                var vb = face.VerticesBeyond;
+                for (int i = 0; i < vb.Count; i++)
+                {
+                    SingularVertices.Add(vb[i]);
+                }
+
+                ConvexFaces.Add(face);
+                UnprocessedFaces.Remove(face);
+                EmptyBufferStack.Push(face.VerticesBeyond);
+                face.VerticesBeyond = EmptyBuffer;
+            }
+        }
+
+        /// <summary>
         /// Fins the convex hull.
         /// </summary>
@@ -890,5 +982,5 @@
                 var currentFace = UnprocessedFaces.First;
                 CurrentVertex = currentFace.FurthestVertex;
-                ConvexHull.Add(CurrentVertex);
+                                                
                 UpdateCenter();
 
@@ -897,5 +989,6 @@
 
                 // Create the cone from the currentVertex and the affected faces horizon.
-                CreateCone();
+                if (!SingularVertices.Contains(CurrentVertex) && CreateCone()) CommitCone();
+                else HandleSingular();
 
                 // Need to reset the tags
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/VertexSort.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/VertexSort.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/MIConvexHull/ConvexHull/VertexSort.cs	(revision 9945)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace MIConvexHull
+{
+    class VertexSort:IComparer<VertexWrap>
+    {
+        private readonly int dimension;
+        public List<VertexWrap> Duplicates { get; private set; } 
+
+        public VertexSort(int Dimension)
+        {
+            this.dimension = Dimension;
+            Duplicates = new List<VertexWrap>();
+        }
+        public int Compare(VertexWrap x, VertexWrap y)
+        {
+            if (x == y) return 0;
+            for (int i = 0; i < dimension; i++)
+            {
+                if (x.PositionData[i] < y.PositionData[i]) return -1;
+                if (x.PositionData[i] > y.PositionData[i]) return 1;
+            }
+            if (isANewDuplicate(x)) Duplicates.Add(x);
+            return 0;
+        }
+
+        private bool isANewDuplicate(VertexWrap x)
+        {
+            for (int i = 0; i < Duplicates.Count; i++)
+            {
+                if (Constants.SamePosition(x.PositionData, Duplicates[i].PositionData, dimension))
+                    return false;
+            }
+            return true;
+        }
+
+    }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Program.cs	(revision 9945)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Diagnostics;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis.AlgorithmBehavior.Analyzers;
+using MIConvexHull;
+
+namespace Visualization {
+  static class Program {
+    /// <summary>
+    /// The main entry point for the application.
+    /// </summary>
+    [STAThread]
+    static void Main() {
+      Application.EnableVisualStyles();
+      Application.SetCompatibleTextRenderingDefault(false);
+
+      int nrOfSamples = 100;
+      int sampleSize = 100;
+      double[][] inputs = CreateRandomData(nrOfSamples, sampleSize);
+
+      var convAlgData = ConvertPermutationToVertex(inputs);
+
+
+      Stopwatch watch = new Stopwatch();
+      watch.Start();
+      var result2 = HyperHull.CalculateUsingSMO(inputs);
+      watch.Stop();
+      Console.WriteLine("HyperHull: " + watch.ElapsedMilliseconds);
+      watch.Restart();
+      var result1 = ConvexHull.Create(convAlgData).Points.Select(x => x.Position).ToList();
+      watch.Stop();
+      Console.WriteLine("MIConvexHull: " + watch.ElapsedMilliseconds);
+
+      int k = 0;
+      foreach (var d in result1) {
+        bool found = false;
+        foreach (var e in result2) {
+          int i = 0;
+          for (i = 0; i < e.Count(); i++) {
+            if (d[i] != e[i]) {
+              break;
+            }
+          }
+          if (i == e.Count()) {
+            found = true;
+            k++;
+            break;
+          }
+        }
+      }
+
+      VisualizationForm vis = new VisualizationForm();
+      vis.Text = "Ratio: " + k + "/" + result1.Count;
+      vis.Inputs = inputs;
+      vis.ConvexHull1 = result1;
+      vis.ConvexHull2 = result2;
+      Application.Run(vis);
+    }
+
+    private static List<DefaultVertex> ConvertPermutationToVertex(double[][] data) {
+      List<DefaultVertex> result = new List<DefaultVertex>();
+      for (int i = 0; i < data.Count(); i++) {
+        double[] d = data[i];
+        for (int j = 0; j < d.Length; j++) {
+          DefaultVertex vertex = new DefaultVertex();
+          vertex.Position = d.Select(x => x).ToArray();
+          result.Add(vertex);
+        }
+      }
+      return result;
+    }
+
+    private static double[][] CreateRandomData(int n, int m) {
+      double[][] result = new double[n][];
+      Random rand = new Random();
+
+      for (int i = 0; i < n; i++) {
+        result[i] = new double[m];
+        for (int j = 0; j < m; j++) {
+          result[i][j] = (double)rand.Next(1, 240);
+        }
+      }
+
+      return result;
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/AssemblyInfo.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/AssemblyInfo.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/AssemblyInfo.cs	(revision 9945)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("VisualizationForm")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("VisualizationForm")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("168f078a-c4d6-4573-aa7d-dac4b0129444")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.Designer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.Designer.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.Designer.cs	(revision 9945)
@@ -0,0 +1,62 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.18052
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Visualization.Properties {
+
+
+  /// <summary>
+  ///   A strongly-typed resource class, for looking up localized strings, etc.
+  /// </summary>
+  // This class was auto-generated by the StronglyTypedResourceBuilder
+  // class via a tool like ResGen or Visual Studio.
+  // To add or remove a member, edit your .ResX file then rerun ResGen
+  // with the /str option, or rebuild your VS project.
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  internal class Resources {
+
+    private static global::System.Resources.ResourceManager resourceMan;
+
+    private static global::System.Globalization.CultureInfo resourceCulture;
+
+    [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+    internal Resources() {
+    }
+
+    /// <summary>
+    ///   Returns the cached ResourceManager instance used by this class.
+    /// </summary>
+    [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+    internal static global::System.Resources.ResourceManager ResourceManager {
+      get {
+        if ((resourceMan == null)) {
+          global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("VisualizationForm.Properties.Resources", typeof(Resources).Assembly);
+          resourceMan = temp;
+        }
+        return resourceMan;
+      }
+    }
+
+    /// <summary>
+    ///   Overrides the current thread's CurrentUICulture property for all
+    ///   resource lookups using this strongly typed resource class.
+    /// </summary>
+    [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+    internal static global::System.Globalization.CultureInfo Culture {
+      get {
+        return resourceCulture;
+      }
+      set {
+        resourceCulture = value;
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.resx
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.resx	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Resources.resx	(revision 9945)
@@ -0,0 +1,117 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.Designer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.Designer.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.Designer.cs	(revision 9945)
@@ -0,0 +1,26 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.18052
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Visualization.Properties {
+
+
+  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+  internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+
+    private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+    public static Settings Default {
+      get {
+        return defaultInstance;
+      }
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.settings
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.settings	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Properties/Settings.settings	(revision 9945)
@@ -0,0 +1,7 @@
+﻿<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.Designer.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.Designer.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.Designer.cs	(revision 9945)
@@ -0,0 +1,60 @@
+﻿namespace Visualization {
+  partial class VisualizationForm {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.pictureBox = new System.Windows.Forms.PictureBox();
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.pictureBox.BackColor = System.Drawing.Color.White;
+      this.pictureBox.Location = new System.Drawing.Point(12, 12);
+      this.pictureBox.Name = "pictureBox";
+      this.pictureBox.Size = new System.Drawing.Size(282, 243);
+      this.pictureBox.TabIndex = 0;
+      this.pictureBox.TabStop = false;
+      // 
+      // VisualizationForm
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.ClientSize = new System.Drawing.Size(306, 267);
+      this.Controls.Add(this.pictureBox);
+      this.Name = "VisualizationForm";
+      this.Text = "VisualizationForm";
+      this.Load += new System.EventHandler(this.Visualization_Load);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.PictureBox pictureBox;
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.cs
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.cs	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.cs	(revision 9945)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace Visualization {
+  public partial class VisualizationForm : Form {
+    public double[][] Inputs { get; set; }
+    public List<double[]> ConvexHull1 { get; set; }
+    public List<double[]> ConvexHull2 { get; set; }
+
+    public VisualizationForm() {
+      InitializeComponent();
+    }
+
+    private void Visualization_Load(object sender, System.EventArgs e) {
+      Draw();
+    }
+
+    private void DrawPixel(int x, int y, Color color, Bitmap image) {
+
+      using (Graphics g = Graphics.FromImage(image)) {
+        using (Brush b = new SolidBrush(color)) {
+          g.FillEllipse(b, x, y, 5, 5);
+        }
+      }
+    }
+
+    private void Draw() {
+      Bitmap image = new Bitmap(pictureBox.Width, pictureBox.Height);
+
+      foreach (var input in Inputs) {
+        DrawPixel((int)input.First(), (int)input.Last(), Color.Black, image);
+      }
+      foreach (var input in ConvexHull1) {
+        DrawPixel((int)input.First() + 1, (int)input.Last() + 1, Color.Red, image);
+      }
+      foreach (var input in ConvexHull2) {
+        DrawPixel((int)input.First(), (int)input.Last(), Color.Blue, image);
+      }
+
+      pictureBox.Image = image;
+    }
+  }
+}
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.csproj
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.csproj	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.csproj	(revision 9945)
@@ -0,0 +1,95 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{E968DFEC-F612-4898-B92A-00A45E2DEE85}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Visualization</RootNamespace>
+    <AssemblyName>Visualization</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Deployment" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Visualization.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Visualization.Designer.cs">
+      <DependentUpon>Visualization.cs</DependentUpon>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <EmbeddedResource Include="Visualization.resx">
+      <DependentUpon>Visualization.cs</DependentUpon>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Analysis.AlgorithmBehavior.Analyzers\3.3\HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj">
+      <Project>{2533d1f9-f7f6-46cb-90d2-76d254e38dee}</Project>
+      <Name>HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\MIConvexHull\MIConvexHull.csproj">
+      <Project>{2337776d-7d0c-40aa-a439-c26c3ce24fab}</Project>
+      <Name>MIConvexHull</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.resx
===================================================================
--- branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.resx	(revision 9945)
+++ branches/HeuristicLab.Analysis.AlgorithmBehavior/Visualization/Visualization.resx	(revision 9945)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
