Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLab.StatisticalAnalysis.csproj
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLab.StatisticalAnalysis.csproj	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLab.StatisticalAnalysis.csproj	(revision 1517)
@@ -0,0 +1,130 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1DAA4952-8D6B-4D43-A9E5-5466053DA777}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.StatisticalAnalysis</RootNamespace>
+    <AssemblyName>HeuristicLab.StatisticalAnalysis-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <StartupObject>
+    </StartupObject>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <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' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="HeuristicLabStatisticalAnalysisPlugin.cs" />
+    <Compile Include="MannWhitneyWilcoxonTest.cs" />
+    <Compile Include="MannWhitneyWilcoxonTestControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="MannWhitneyWilcoxonTestControl.Designer.cs">
+      <DependentUpon>MannWhitneyWilcoxonTestControl.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Random\HeuristicLab.Random.csproj">
+      <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
+      <Name>HeuristicLab.Random</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="MannWhitneyWilcoxonTestControl.resx">
+      <DependentUpon>MannWhitneyWilcoxonTestControl.cs</DependentUpon>
+    </EmbeddedResource>
+  </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>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLabStatisticalAnalysisPlugin.cs
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLabStatisticalAnalysisPlugin.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/HeuristicLabStatisticalAnalysisPlugin.cs	(revision 1517)
@@ -0,0 +1,35 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2009 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.StatisticalAnalysis {
+  [ClassInfo(Name = "HeuristicLab.StatisticalAnalysis-3.2")]
+  [PluginFile(Filename = "HeuristicLab.StatisticalAnalysis-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  public class HeuristicLabStatisticalAnalysisPlugin : PluginBase {
+  }
+}
Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTest.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTest.cs	(revision 1517)
@@ -0,0 +1,408 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2009 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Random;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.StatisticalAnalysis {
+  public class MannWhitneyWilcoxonTest : IEditable {
+
+    public IView CreateView() {
+      return CreateEditor();
+    }
+
+    public IEditor CreateEditor() {
+      return new MannWhitneyWilcoxonTestControl();
+    }
+
+    /// <summary>
+    /// Calculates the p-value of a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test).
+    /// The test performs a ranking of the data and returns the p-value indicating the level of significance
+    /// at which the hypothesis H0 can be rejected.
+    /// Caution: This method approximates the ranks in p1 and p2 with a normal distribution and should only be called
+    /// when the sample size is at least 10 in both samples.
+    /// 
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <returns>The p-value of the test</returns>
+    public static double TwoTailedTest(double[] p1, double[] p2) {
+      double rank = MannWhitneyWilcoxonTest.CalculateRankSumForP1(p1, p2);
+      return MannWhitneyWilcoxonTest.ApproximatePValue(rank, p1.Length, p2.Length, true);
+    }
+
+    /// <summary>
+    /// Calculates whether a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test)
+    /// would reject the hypothesis H0 that the given two populations stem from the same distribution.
+    /// The alternative hypothesis would be that they come from different distributions.
+    /// The test performs a ranking of the data and decides based on the ranking whehter to reject the
+    /// hypothesis or not.
+    /// 
+    /// If there are less than 20 samples in each population this decision is based on a table lookup.
+    /// If one array consists of more than 20 samples, it will approximate the distribution by a normal
+    /// distribution. In the case of the table lookup, alpha is restricted to 0.01, 0.05, and 0.1.
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <param name="alpha">The significance level. If p1 and p2 are both smaller or equal than 20, the decision is based on three tables that represent significance at 0.01, 0.05, and 0.1.</param>
+    /// <returns>True if H0 (p1 equals p2) can be rejected, False otherwise</returns>
+    public static bool TwoTailedTest(double[] p1, double[] p2, double alpha) {
+      return MannWhitneyWilcoxonTest.TwoTailedTest(p1, p2, alpha, 20);
+    }
+
+    /// <summary>
+    /// Calculates whether a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test)
+    /// would reject the hypothesis H0 that the given two populations stem from the same distribution.
+    /// The alternative hypothesis would be that they come from different distributions.
+    /// The test performs a ranking of the data and decides based on the ranking whehter to reject the
+    /// hypothesis or not.
+    /// 
+    /// If there are less than <paramref name="approximationLevel"/> samples in each population this
+    /// decision is based on a table lookup.
+    /// If one array consists of more than <paramref name="approximationLevel"/> samples, it will
+    /// approximate the distribution by a normal distribution. In the case of the table lookup,
+    /// alpha is restricted to 0.01, 0.05, and 0.1.
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <param name="alpha">The significance level. If p1 and p2 are both smaller or equal than 20,
+    /// the decision is based on three tables that represent significance at 0.01, 0.05, and 0.1.</param>
+    /// <param name="approximationLevel">Defines at which sample size to use normal approximation,
+    /// instead of the table lookup. If a higher value than 20 is specified, the value 20 will be
+    /// used instead, if 0 is specified the result will be compuated always by approximation.</param>
+    /// <returns>True if H0 (p1 equals p2) can be rejected, False otherwise</returns>
+    public static bool TwoTailedTest(double[] p1, double[] p2, double alpha, int approximationLevel) {
+      Array.Sort<double>(p1);
+      Array.Sort<double>(p2);
+      int n1 = p1.Length, n2 = p2.Length;
+
+      double R1 = MannWhitneyWilcoxonTest.CalculateRankSumForP1(p1, p2);
+
+      if (n1 <= Math.Min(approximationLevel, 20) && n2 <= Math.Min(approximationLevel, 20)) {
+        return MannWhitneyWilcoxonTest.AbsolutePValue(R1, n1, n2, alpha, true);
+      } else { // normal approximation
+        return MannWhitneyWilcoxonTest.ApproximatePValue(R1, n1, n2, true) <= alpha;
+      }
+    }
+
+    /// <summary>
+    /// Calculates the p-value of a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test).
+    /// The test performs a ranking of the data and returns the p-value indicating the level of significance
+    /// at which the hypothesis H0 can be rejected.
+    /// Caution: This method approximates the ranks in p1 and p2 with a normal distribution and should only be called
+    /// when the sample size is at least 10 in both samples.
+    /// 
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <returns>The p-value of the test</returns>
+    public static double TwoTailedTest(int[] p1, int[] p2) {
+      double rank = MannWhitneyWilcoxonTest.CalculateRankSumForP1(p1, p2);
+      return MannWhitneyWilcoxonTest.ApproximatePValue(rank, p1.Length, p2.Length, true);
+    }
+
+    /// <summary>
+    /// Calculates whether a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test)
+    /// would reject the hypothesis H0 that the given two populations stem from the same distribution.
+    /// The alternative hypothesis would be that they come from different distributions.
+    /// The test performs a ranking of the data and decides based on the ranking whehter to reject the
+    /// hypothesis or not.
+    /// 
+    /// If there are less than 20 samples in each population this decision is based on a table lookup.
+    /// If one array consists of more than 20 samples, it will approximate the distribution by a normal
+    /// distribution. In the case of the table lookup, alpha is restricted to 0.01, 0.05, and 0.1.
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <param name="alpha">The significance level. If p1 and p2 are both smaller or equal than 20, the decision is based on three tables that represent significance at 0.01, 0.05, and 0.1.</param>
+    /// <returns>True if H0 (p1 equals p2) can be rejected, False otherwise</returns>
+    public static bool TwoTailedTest(int[] p1, int[] p2, double alpha) {
+      return MannWhitneyWilcoxonTest.TwoTailedTest(p1, p2, alpha, 20);
+    }
+
+    /// <summary>
+    /// Calculates whether a 2-tailed Mann Whitney Wilcoxon U-test (also known as Mann Whitney rank sum test)
+    /// would reject the hypothesis H0 that the given two populations stem from the same distribution.
+    /// The alternative hypothesis would be that they come from different distributions.
+    /// The test performs a ranking of the data and decides based on the ranking whehter to reject the
+    /// hypothesis or not.
+    /// 
+    /// If there are less than <paramref name="approximationLevel"/> samples in each population this
+    /// decision is based on a table lookup.
+    /// If one array consists of more than <paramref name="approximationLevel"/> samples, it will
+    /// approximate the distribution by a normal distribution. In the case of the table lookup,
+    /// alpha is restricted to 0.01, 0.05, and 0.1.
+    /// </summary>
+    /// <param name="p1">Array with samples from population 1</param>
+    /// <param name="p2">Array with samples from population 2</param>
+    /// <param name="alpha">The significance level. If p1 and p2 are both smaller or equal than 20,
+    /// the decision is based on three tables that represent significance at 0.01, 0.05, and 0.1.</param>
+    /// <param name="approximationLevel">Defines at which sample size to use normal approximation,
+    /// instead of the table lookup. If a higher value than 20 is specified, the value 20 will be
+    /// used instead, if 0 is specified the result will be compuated always by approximation.</param>
+    /// <returns>True if H0 (p1 equals p2) can be rejected, False otherwise</returns>
+    public static bool TwoTailedTest(int[] p1, int[] p2, double alpha, int approximationLevel) {
+      Array.Sort<int>(p1);
+      Array.Sort<int>(p2);
+      int n1 = p1.Length, n2 = p2.Length;
+      
+      double R1 = MannWhitneyWilcoxonTest.CalculateRankSumForP1(p1, p2);
+
+      if (n1 <= Math.Min(approximationLevel, 20) && n2 <= Math.Min(approximationLevel, 20)) {
+        return MannWhitneyWilcoxonTest.AbsolutePValue(R1, n1, n2, alpha, true);
+      } else {
+        return MannWhitneyWilcoxonTest.ApproximatePValue(R1, n1, n2, true) <= alpha;
+      }
+    }
+
+    private static bool AbsolutePValue(double rank, int nRank, int nOther, double alpha, bool twoTailed) {
+      double U1 = rank - (double)(nRank * (nRank + 1) / 2);
+      double U2 = (double)(nRank * nOther) - U1;
+      if (alpha <= 0.01) {
+        return (Math.Min(U1, U2) <= table001[nRank - 1, nOther - 1]);
+      } else if (alpha <= 0.05) {
+        return (Math.Min(U1, U2) <= table005[nRank - 1, nOther - 1]);
+      } else if (alpha <= 0.1) {
+        return (Math.Min(U1, U2) <= table01[nRank - 1, nOther - 1]);
+      } else throw new ArgumentException("ERROR in MannWhitneyWilcoxonTest: alpha must be <= 0.1");
+    }
+
+    private static double ApproximatePValue(double rank, int nRank, int nOther, bool twoTailed) {
+      double U1 = rank - (double)(nRank * (nRank + 1) / 2);
+      double U2 = (double)(nRank * nOther) - U1;
+
+      double mu = nRank * nOther / 2;
+      double sigma = Math.Sqrt(nRank * nOther * (nRank + nOther + 1) / 12);
+      double z = (Math.Min(U1, U2) - mu) / sigma;
+      return ProbabilityOfZValue(z);
+    }
+
+    // FIXME: when there's equality among some samples within a population the rank also needs to be averaged
+    private static double CalculateRankSumForP1(int[] p1, int[] p2) {
+      int rank = 0, p2Idx = 0;
+      int n1 = p1.Length, n2 = p2.Length;
+      double R1 = 0;
+
+      for (int i = 0; i < n1; i++) {
+        rank++;
+        if (p1[i] < p2[p2Idx]) {
+          R1 += rank;
+        } if (p1[i] == p2[p2Idx]) {
+          int startRank = rank;
+          rank++;
+          int commonRank = startRank + rank;
+          int starti = i;
+          while (i + 1 < n1 && Math.Abs(p1[i + 1] - p2[p2Idx]) < 1e-07) {
+            i++;
+            rank++;
+            commonRank += rank;
+          }
+          while (p2Idx + 1 < n2 && Math.Abs(p1[i] - p2[p2Idx + 1]) < 1e-07) {
+            p2Idx++;
+            rank++;
+            commonRank += rank;
+          }
+          p2Idx++;
+          R1 += (i - starti + 1) * commonRank / (rank - startRank + 1);
+        } else {
+          p2Idx++;
+          i--;
+        }
+        if (p2Idx == n2) {
+          i++; rank++; // calculate the rest of the ranks for p1
+          while (i < n1) {
+            R1 += rank;
+            rank++;
+            i++;
+          }
+          break;
+        }
+      }
+      return R1;
+    }
+
+    private static double CalculateRankSumForP2(int[] p1, int[] p2) {
+      int n1 = p1.Length, n2 = p2.Length;
+      double completeRankSum = (double)((n1 + n2 + 1) * (n1 + n2)) / 2.0;
+      return completeRankSum - CalculateRankSumForP1(p1, p2);
+    }
+
+    // FIXME: when there's equality among some samples within a population the rank also needs to be averaged
+    private static double CalculateRankSumForP1(double[] p1, double[] p2) {
+      int rank = 0, n1 = p1.Length, n2 = p2.Length, p2Idx = 0;
+      double R1 = 0;
+
+      for (int i = 0; i < n1; i++) {
+        rank++;
+        if (Math.Abs(p1[i] - p2[p2Idx]) < 1e-07) {
+          int startRank = rank;
+          rank++;
+          int commonRank = startRank + rank;
+          int starti = i;
+          while (i + 1 < n1 && Math.Abs(p1[i + 1] - p2[p2Idx]) < 1e-07) {
+            i++;
+            rank++;
+            commonRank += rank;
+          }
+          while (p2Idx + 1 < n2 && Math.Abs(p1[i] - p2[p2Idx + 1]) < 1e-07) {
+            p2Idx++;
+            rank++;
+            commonRank += rank;
+          }
+          p2Idx++;
+          R1 += (i - starti + 1) * commonRank / (rank - startRank + 1);
+        } else if (p1[i] < p2[p2Idx]) {
+          R1 += rank;
+        } else {
+          p2Idx++;
+          i--;
+        }
+        if (p2Idx == n2) {
+          i++; rank++; // calculate the rest of the ranks for p1
+          while (i < n1) {
+            R1 += rank;
+            rank++;
+            i++;
+          }
+          break;
+        }
+      }
+      return R1;
+    }
+
+    private static double CalculateRankSumForP2(double[] p1, double[] p2) {
+      int n1 = p1.Length, n2 = p2.Length;
+      double completeRankSum = (double)((n1 + n2 + 1) * (n1 + n2)) / 2.0;
+      return completeRankSum - CalculateRankSumForP1(p1, p2);
+    }
+
+    // taken from: http://www.fourmilab.ch/rpkp/experiments/analysis/zCalc.html (in public domain)
+    private static double ProbabilityOfZValue(double z) {
+      double y, x, w, zMax = 6.0;
+      if (Math.Abs(z) < 1e-07) {
+        x = 0.0;
+      } else {
+        y = 0.5 * Math.Abs(z);
+        if (y > (zMax * 0.5)) {
+          x = 1.0;
+        } else if (y < 1.0) {
+          w = y * y;
+          x = ((((((((0.000124818987 * w
+                   - 0.001075204047) * w + 0.005198775019) * w
+                   - 0.019198292004) * w + 0.059054035642) * w
+                   - 0.151968751364) * w + 0.319152932694) * w
+                   - 0.531923007300) * w + 0.797884560593) * y * 2.0;
+        } else {
+          y -= 2.0;
+          x = (((((((((((((-0.000045255659 * y
+                         + 0.000152529290) * y - 0.000019538132) * y
+                         - 0.000676904986) * y + 0.001390604284) * y
+                         - 0.000794620820) * y - 0.002034254874) * y
+                         + 0.006549791214) * y - 0.010557625006) * y
+                         + 0.011630447319) * y - 0.009279453341) * y
+                         + 0.005353579108) * y - 0.002141268741) * y
+                         + 0.000535310849) * y + 0.999936657524;
+        }
+      }
+      return (z > 0.0) ? ((x + 1.0) * 0.5) : ((1.0 - x) * 0.5);
+    }
+
+    #region probability tables
+    // table stems from
+    // Roy C. Milton. An Extended Table of Critical Values for the Mann-Whitney (Wilcoxon) Two-Sample Statistic. Journal of the American Statistical Association, Vol. 59, No. 307 (Sep., 1964), pp. 925-934.
+    private static int[,] table01 = new int[20, 20] {
+      /*         1   2   3   4   5   6   7   8   9  10  11  12  13  14   15   16   17   18   19   20*/
+      /*  1 */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1,  -1,  -1,  -1,   0,   0},
+      /*  2 */{ -1, -1, -1, -1,  0,  0,  0,  1,  1,  1,  1,  2,  2,  3,   3,   3,   3,   4,   4,   4},
+      /*  3 */{ -1, -1,  0,  0,  1,  2,  2,  3,  4,  4,  5,  5,  6,  7,   7,   8,   9,   9,  10,  11},
+      /*  4 */{ -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11,  12,  14,  15,  16,  17,  18},
+      /*  5 */{ -1,  0,  1,  2,  4,  5,  6,  8,  9, 11, 12, 13, 15, 16,  18,  19,  20,  22,  23,  25},
+      /*  6 */{ -1,  0,  2,  3,  5,  7,  8, 10, 12, 14, 16, 17, 19, 21,  23,  25,  26,  28,  30,  32},
+      /*  7 */{ -1,  0,  2,  4,  6,  8, 11, 13, 15, 17, 19, 21, 24, 26,  28,  30,  33,  35,  37,  39},
+      /*  8 */{ -1,  1,  3,  5,  8, 10, 13, 15, 18, 20, 23, 26, 28, 31,  33,  36,  39,  41,  44,  47},
+      /*  9 */{ -1,  1,  4,  6,  9, 12, 15, 18, 21, 24, 27, 30, 33, 36,  39,  42,  45,  48,  51,  54},
+      /* 10 */{ -1,  1,  4,  7, 11, 14, 17, 20, 24, 27, 31, 34, 37, 41,  44,  48,  51,  55,  58,  62},
+      /* 11 */{ -1,  1,  5,  8, 12, 16, 19, 23, 27, 31, 34, 38, 42, 46,  50,  54,  57,  61,  65,  69},
+      /* 12 */{ -1,  2,  5,  9, 13, 17, 21, 26, 30, 34, 38, 42, 47, 51,  55,  60,  64,  68,  72,  77},
+      /* 13 */{ -1,  2,  6, 10, 15, 19, 24, 28, 33, 37, 42, 47, 51, 56,  61,  65,  70,  75,  80,  84},
+      /* 14 */{ -1,  3,  7, 11, 16, 21, 26, 31, 36, 41, 46, 51, 56, 61,  66,  71,  77,  82,  87,  92},
+      /* 15 */{ -1,  3,  7, 12, 18, 23, 28, 33, 39, 44, 50, 55, 61, 66,  72,  77,  83,  88,  94, 100},
+      /* 16 */{ -1,  3,  8, 14, 19, 25, 30, 36, 42, 48, 54, 60, 65, 71,  77,  83,  89,  95, 101, 107},
+      /* 17 */{ -1,  3,  9, 15, 20, 26, 33, 39, 45, 51, 57, 64, 70, 77,  83,  89,  96, 102, 109, 115},
+      /* 18 */{ -1,  4,  9, 16, 22, 28, 35, 41, 48, 55, 61, 68, 75, 82,  88,  95, 102, 109, 116, 123},
+      /* 19 */{  0,  4, 10, 17, 23, 30, 37, 44, 51, 58, 65, 72, 80, 87,  94, 101, 109, 116, 123, 130},
+      /* 20 */{  0,  4, 11, 18, 25, 32, 39, 47, 54, 62, 69, 77, 84, 92, 100, 107, 115, 123, 130, 138}};
+
+    // table stems from http://math.usask.ca/~laverty/S245/Tables/wmw.pdf
+    private static int[,] table005 = new int[20, 20] {
+      /*         1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16   17   18   19   20*/
+      /*  1 */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1,  -1,  -1,  -1},
+      /*  2 */{ -1, -1, -1, -1, -1, -1, -1,  0,  0,  0,  0,  1,  1,  1,  1,  1,   2,   2,   2,   2},
+      /*  3 */{ -1, -1, -1, -1,  0,  1,  1,  2,  2,  3,  3,  4,  4,  5,  5,  6,   6,   7,   7,   8},
+      /*  4 */{ -1, -1, -1,  0,  1,  2,  3,  4,  4,  5,  6,  7,  8,  9, 10, 11,  11,  12,  13,  13},
+      /*  5 */{ -1, -1,  0,  1,  2,  3,  5,  6,  7,  8,  9, 11, 12, 13, 14, 15,  17,  18,  19,  20},
+      /*  6 */{ -1, -1,  1,  2,  3,  5,  6,  8, 10, 11, 13, 14, 16, 17, 19, 21,  22,  24,  25,  27},
+      /*  7 */{ -1, -1,  1,  3,  5,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26,  28,  30,  32,  34},
+      /*  8 */{ -1,  0,  2,  4,  6,  8, 10, 13, 15, 17, 19, 22, 24, 26, 29, 31,  34,  36,  38,  41},
+      /*  9 */{ -1,  0,  2,  4,  7, 10, 12, 15, 17, 21, 23, 26, 28, 31, 34, 37,  39,  42,  45,  48},
+      /* 10 */{ -1,  0,  3,  5,  8, 11, 14, 17, 20, 23, 26, 29, 33, 36, 39, 42,  45,  48,  52,  55},
+      /* 11 */{ -1,  0,  3,  6,  9, 13, 16, 19, 23, 26, 30, 33, 37, 40, 44, 47,  51,  55,  58,  62},
+      /* 12 */{ -1,  1,  4,  7, 11, 14, 18, 22, 26, 29, 33, 37, 41, 45, 49, 53,  57,  61,  65,  69},
+      /* 13 */{ -1,  1,  4,  8, 12, 16, 20, 24, 28, 33, 37, 41, 45, 50, 54, 59,  63,  67,  72,  76},
+      /* 14 */{ -1,  1,  5,  9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55, 59, 64,  67,  74,  78,  83},
+      /* 15 */{ -1,  1,  5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64, 70,  75,  80,  85,  90},
+      /* 16 */{ -1,  1,  6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75,  81,  86,  92,  98},
+      /* 17 */{ -1,  2,  6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81,  87,  93,  99, 105},
+      /* 18 */{ -1,  2,  7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86,  93,  99, 106, 112},
+      /* 19 */{ -1,  2,  7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92,  99, 106, 113, 119},
+      /* 20 */{ -1,  2,  8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127}};
+
+    // table from: http://math.usask.ca/~laverty/S245/Tables/wmw.pdf
+    private static int[,] table001 = new int[20, 20] {
+      /*         1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18  19   20*/
+      /*  1 */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  -1},
+      /*  2 */{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  0,   0},
+      /*  3 */{ -1, -1, -1, -1, -1, -1, -1, -1,  0,  0,  0,  1,  1,  1,  2,  2,  2,  2,  3,   3},
+      /*  4 */{ -1, -1, -1, -1, -1,  0,  0,  1,  1,  2,  2,  3,  3,  4,  5,  5,  6,  6,  7,   8},
+      /*  5 */{ -1, -1, -1, -1,  0,  1,  1,  2,  3,  4,  5,  6,  7,  7,  8,  9, 10, 11, 12,  13},
+      /*  6 */{ -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  9, 10, 11, 12, 13, 15, 16, 17,  18},
+      /*  7 */{ -1, -1, -1,  0,  1,  3,  4,  6,  7,  9, 10, 12, 13, 15, 16, 18, 19, 21, 22,  24},
+      /*  8 */{ -1, -1, -1,  1,  2,  4,  6,  7,  9, 11, 13, 15, 17, 18, 20, 22, 24, 26, 28,  30},
+      /*  9 */{ -1, -1,  0,  1,  3,  5,  7,  9, 11, 13, 16, 18, 20, 22, 24, 27, 29, 31, 33,  36},
+      /* 10 */{ -1, -1,  0,  2,  4,  6,  9, 11, 13, 16, 18, 21, 24, 26, 29, 31, 34, 37, 39,  42},
+      /* 11 */{ -1, -1,  0,  2,  5,  7, 10, 13, 16, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45,  46},
+      /* 12 */{ -1, -1,  1,  3,  6,  9, 12, 15, 18, 21, 24, 27, 31, 34, 37, 41, 44, 47, 51,  54},
+      /* 13 */{ -1, -1,  1,  3,  7, 10, 13, 17, 20, 24, 27, 31, 34, 38, 42, 45, 49, 53, 56,  60},
+      /* 14 */{ -1, -1,  1,  4,  7, 11, 15, 18, 22, 26, 30, 34, 38, 42, 46, 50, 54, 58, 63,  67},
+      /* 15 */{ -1, -1,  2,  5,  8, 12, 16, 20, 24, 29, 33, 37, 42, 46, 51, 55, 60, 64, 69,  73},
+      /* 16 */{ -1, -1,  2,  5,  9, 13, 18, 22, 27, 31, 36, 41, 45, 50, 55, 60, 65, 70, 74,  79},
+      /* 17 */{ -1, -1,  2,  6, 10, 15, 19, 24, 29, 34, 39, 44, 49, 54, 60, 65, 70, 75, 81,  86},
+      /* 18 */{ -1, -1,  2,  6, 11, 16, 21, 26, 31, 37, 42, 47, 53, 58, 64, 70, 75, 81, 87,  92},
+      /* 19 */{ -1,  0,  3,  7, 12, 17, 22, 28, 33, 39, 45, 51, 56, 63, 69, 74, 81, 87, 93,  99},
+      /* 20 */{ -1,  0,  3,  8, 13, 18, 24, 30, 36, 42, 46, 54, 60, 67, 73, 79, 86, 92, 99, 105}};
+    #endregion
+
+  }
+}
Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.Designer.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.Designer.cs	(revision 1517)
@@ -0,0 +1,175 @@
+﻿namespace HeuristicLab.StatisticalAnalysis {
+  partial class MannWhitneyWilcoxonTestControl {
+    /// <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 Component 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.label1 = new System.Windows.Forms.Label();
+      this.label2 = new System.Windows.Forms.Label();
+      this.p1TextBox = new System.Windows.Forms.TextBox();
+      this.p2TextBox = new System.Windows.Forms.TextBox();
+      this.label3 = new System.Windows.Forms.Label();
+      this.resultLabel = new System.Windows.Forms.Label();
+      this.testExactButton = new System.Windows.Forms.Button();
+      this.testApproximateButton = new System.Windows.Forms.Button();
+      this.panel1 = new System.Windows.Forms.Panel();
+      this.panel2 = new System.Windows.Forms.Panel();
+      this.alphaTextBox = new System.Windows.Forms.TextBox();
+      this.panel1.SuspendLayout();
+      this.panel2.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(11, 25);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(54, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Sample 1:";
+      // 
+      // label2
+      // 
+      this.label2.AutoSize = true;
+      this.label2.Location = new System.Drawing.Point(11, 51);
+      this.label2.Name = "label2";
+      this.label2.Size = new System.Drawing.Size(54, 13);
+      this.label2.TabIndex = 1;
+      this.label2.Text = "Sample 2:";
+      // 
+      // p1TextBox
+      // 
+      this.p1TextBox.Location = new System.Drawing.Point(71, 22);
+      this.p1TextBox.Name = "p1TextBox";
+      this.p1TextBox.Size = new System.Drawing.Size(219, 20);
+      this.p1TextBox.TabIndex = 2;
+      // 
+      // p2TextBox
+      // 
+      this.p2TextBox.Location = new System.Drawing.Point(71, 48);
+      this.p2TextBox.Name = "p2TextBox";
+      this.p2TextBox.Size = new System.Drawing.Size(219, 20);
+      this.p2TextBox.TabIndex = 3;
+      // 
+      // label3
+      // 
+      this.label3.AutoSize = true;
+      this.label3.Location = new System.Drawing.Point(28, 78);
+      this.label3.Name = "label3";
+      this.label3.Size = new System.Drawing.Size(37, 13);
+      this.label3.TabIndex = 4;
+      this.label3.Text = "Alpha:";
+      // 
+      // resultLabel
+      // 
+      this.resultLabel.AutoSize = true;
+      this.resultLabel.Location = new System.Drawing.Point(4, 4);
+      this.resultLabel.MaximumSize = new System.Drawing.Size(265, 80);
+      this.resultLabel.Name = "resultLabel";
+      this.resultLabel.Size = new System.Drawing.Size(40, 13);
+      this.resultLabel.TabIndex = 5;
+      this.resultLabel.Text = "Result:";
+      // 
+      // testExactButton
+      // 
+      this.testExactButton.Location = new System.Drawing.Point(215, 103);
+      this.testExactButton.Name = "testExactButton";
+      this.testExactButton.Size = new System.Drawing.Size(75, 23);
+      this.testExactButton.TabIndex = 8;
+      this.testExactButton.Text = "Exact";
+      this.testExactButton.UseVisualStyleBackColor = true;
+      this.testExactButton.Click += new System.EventHandler(this.testExactButton_Click);
+      // 
+      // testApproximateButton
+      // 
+      this.testApproximateButton.Location = new System.Drawing.Point(215, 74);
+      this.testApproximateButton.Name = "testApproximateButton";
+      this.testApproximateButton.Size = new System.Drawing.Size(75, 23);
+      this.testApproximateButton.TabIndex = 9;
+      this.testApproximateButton.Text = "Approximate";
+      this.testApproximateButton.UseVisualStyleBackColor = true;
+      this.testApproximateButton.Click += new System.EventHandler(this.testApproximateButton_Click);
+      // 
+      // panel1
+      // 
+      this.panel1.Anchor = System.Windows.Forms.AnchorStyles.None;
+      this.panel1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
+      this.panel1.Controls.Add(this.alphaTextBox);
+      this.panel1.Controls.Add(this.panel2);
+      this.panel1.Controls.Add(this.testExactButton);
+      this.panel1.Controls.Add(this.testApproximateButton);
+      this.panel1.Controls.Add(this.label1);
+      this.panel1.Controls.Add(this.label2);
+      this.panel1.Controls.Add(this.p1TextBox);
+      this.panel1.Controls.Add(this.p2TextBox);
+      this.panel1.Controls.Add(this.label3);
+      this.panel1.Location = new System.Drawing.Point(3, 3);
+      this.panel1.Name = "panel1";
+      this.panel1.Size = new System.Drawing.Size(309, 248);
+      this.panel1.TabIndex = 10;
+      // 
+      // panel2
+      // 
+      this.panel2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.panel2.Controls.Add(this.resultLabel);
+      this.panel2.Location = new System.Drawing.Point(14, 132);
+      this.panel2.Name = "panel2";
+      this.panel2.Size = new System.Drawing.Size(276, 90);
+      this.panel2.TabIndex = 10;
+      // 
+      // alphaTextBox
+      // 
+      this.alphaTextBox.Location = new System.Drawing.Point(71, 75);
+      this.alphaTextBox.Name = "alphaTextBox";
+      this.alphaTextBox.Size = new System.Drawing.Size(84, 20);
+      this.alphaTextBox.TabIndex = 11;
+      // 
+      // MannWhitneyWilcoxonTestControl
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.panel1);
+      this.Name = "MannWhitneyWilcoxonTestControl";
+      this.Size = new System.Drawing.Size(316, 255);
+      this.panel1.ResumeLayout(false);
+      this.panel1.PerformLayout();
+      this.panel2.ResumeLayout(false);
+      this.panel2.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.Label label2;
+    private System.Windows.Forms.TextBox p1TextBox;
+    private System.Windows.Forms.TextBox p2TextBox;
+    private System.Windows.Forms.Label label3;
+    private System.Windows.Forms.Label resultLabel;
+    private System.Windows.Forms.Button testExactButton;
+    private System.Windows.Forms.Button testApproximateButton;
+    private System.Windows.Forms.Panel panel1;
+    private System.Windows.Forms.Panel panel2;
+    private System.Windows.Forms.TextBox alphaTextBox;
+  }
+}
Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.cs
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.cs	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.cs	(revision 1517)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2009 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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.StatisticalAnalysis {
+  public partial class MannWhitneyWilcoxonTestControl : EditorBase {
+    public MannWhitneyWilcoxonTestControl()
+      : base() {
+      InitializeComponent();
+      alphaTextBox.Text = ((double)0.05).ToString();
+    }
+
+    private void ArrayToString<T>(T[] array, TextBox p) {
+      StringBuilder s = new StringBuilder();
+      foreach (T element in array)
+        s.Append(element + "; ");
+      s.Remove(s.Length - 2, 2);
+      p.Text = s.ToString();
+    }
+
+    private double[] ConvertStringToArray(TextBox p) {
+      string t = p.Text;
+      string[] s = t.Split(new char[] { ';' });
+      double[] tmp = new double[s.Length];
+      try {
+        for (int i = 0; i < s.Length; i++) {
+          tmp[i] = double.Parse(s[i]);
+        }
+      }
+      catch (FormatException) {
+        return null;
+      }
+      return tmp;
+    }
+
+    private void testApproximateButton_Click(object sender, EventArgs e) {
+      double[] p1 = ConvertStringToArray(p1TextBox);
+      double[] p2 = ConvertStringToArray(p2TextBox);
+      if (p1.Length < 10 || p2.Length < 10) {
+        MessageBox.Show("Sample size is too small to approximate, provide at least 10 samples in each population.");
+        return;
+      }
+      double alpha = Double.Parse(alphaTextBox.Text);
+      double pVal = MannWhitneyWilcoxonTest.TwoTailedTest(p1, p2);
+      if (pVal <= alpha) {
+        resultLabel.Text = "The hypothesis H0 can be rejected at " + alpha.ToString() + ", the p-Value is " + pVal.ToString() + "\nThe samples are likely not to stem from the same distribution.";
+      } else {
+        resultLabel.Text = "The hypothesis H0 cannot be rejected at " + alpha.ToString();
+      }
+    }
+
+    private void testExactButton_Click(object sender, EventArgs e) {
+      double[] p1 = ConvertStringToArray(p1TextBox);
+      double[] p2 = ConvertStringToArray(p2TextBox);
+      if (p1.Length > 20 || p2.Length > 20) {
+        MessageBox.Show("Sample size is too large for exact calculation, do not use more than 20 samples in each population.");
+        return;
+      }
+      double alpha = Double.Parse(alphaTextBox.Text);
+      if (MannWhitneyWilcoxonTest.TwoTailedTest(p1, p2, alpha)) {
+        resultLabel.Text = "The hypothesis H0 can be rejected at " + alpha.ToString() + "\nThe samples are likely not to stem from the same distribution.";
+      } else {
+        resultLabel.Text = "The hypothesis H0 cannot be rejected at " + alpha.ToString();
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.resx
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.resx	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/MannWhitneyWilcoxonTestControl.resx	(revision 1517)
@@ -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=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: /trunk/sources/HeuristicLab.StatisticalAnalysis/Properties/AssemblyInfo.frame
===================================================================
--- /trunk/sources/HeuristicLab.StatisticalAnalysis/Properties/AssemblyInfo.frame	(revision 1517)
+++ /trunk/sources/HeuristicLab.StatisticalAnalysis/Properties/AssemblyInfo.frame	(revision 1517)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2009 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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("HeuristicLab.StatisticalAnalysis")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("HEAL")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2009 HEAL")]
+[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("2b7165ae-965a-4e77-b878-51c6276203eb")]
+
+// 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("3.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: /trunk/sources/HeuristicLab.sln
===================================================================
--- /trunk/sources/HeuristicLab.sln	(revision 1516)
+++ /trunk/sources/HeuristicLab.sln	(revision 1517)
@@ -156,4 +156,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Tracing", "HeuristicLab.Tracing\HeuristicLab.Tracing.csproj", "{EE2034D9-6E27-48A1-B855-42D45F69A4FC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.StatisticalAnalysis", "HeuristicLab.StatisticalAnalysis\HeuristicLab.StatisticalAnalysis.csproj", "{1DAA4952-8D6B-4D43-A9E5-5466053DA777}"
 EndProject
 Global
@@ -1241,6 +1243,5 @@
 		{6AEF1284-2428-4B01-B9D2-62C1FA7C2DE1}.Visualization Debug|x86.Build.0 = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.CEDMA Debug|Any CPU.ActiveCfg = Debug|x86
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.CEDMA Debug|x64.ActiveCfg = Debug|x64
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.CEDMA Debug|x64.Build.0 = Debug|x64
+		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.CEDMA Debug|x86.ActiveCfg = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -1251,17 +1252,14 @@
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Debug|x86.Build.0 = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|x64.ActiveCfg = Debug|x64
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|x64.Build.0 = Debug|x64
+		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|x64.ActiveCfg = Debug|Any CPU
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|x86.ActiveCfg = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.GP Debug|x86.Build.0 = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|Any CPU.Build.0 = Release|Any CPU
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|x64.ActiveCfg = Release|x64
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|x64.Build.0 = Release|x64
+		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|x64.ActiveCfg = Release|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|x86.ActiveCfg = Release|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Release|x86.Build.0 = Release|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|x64.ActiveCfg = Debug|x64
-		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|x64.Build.0 = Debug|x64
+		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|x86.ActiveCfg = Debug|x86
 		{32DAA44F-944A-465F-A5C9-1C491EE4976D}.Visualization Debug|x86.Build.0 = Debug|x86
@@ -2147,4 +2145,26 @@
 		{EE2034D9-6E27-48A1-B855-42D45F69A4FC}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU
 		{EE2034D9-6E27-48A1-B855-42D45F69A4FC}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|x64.ActiveCfg = Debug|x64
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|x64.Build.0 = Debug|x64
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|x86.ActiveCfg = Debug|x86
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Debug|x86.Build.0 = Debug|x86
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.GP Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.GP Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.GP Debug|x64.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.GP Debug|x86.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Release|x64.ActiveCfg = Release|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Release|x86.ActiveCfg = Release|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU
+		{1DAA4952-8D6B-4D43-A9E5-5466053DA777}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /trunk/sources/HeuristicLab/CopyAssemblies.cmd
===================================================================
--- /trunk/sources/HeuristicLab/CopyAssemblies.cmd	(revision 1516)
+++ /trunk/sources/HeuristicLab/CopyAssemblies.cmd	(revision 1517)
@@ -78,4 +78,5 @@
 copy "%SolutionDir%\HeuristicLab.SQLite\SQLite License.txt" .\plugins
 copy "%SolutionDir%\HeuristicLab.SQLite\SQLite.NET.chm" .\plugins
+copy "%SolutionDir%\HeuristicLab.StatisticalAnalysis\%Outdir%\HeuristicLab.StatisticalAnalysis-3.2.dll" .\plugins
 copy "%SolutionDir%\HeuristicLab.TestFunctions\%Outdir%\HeuristicLab.TestFunctions-3.2.dll" .\plugins
 copy "%SolutionDir%\HeuristicLab.ThreadParallelEngine\%Outdir%\HeuristicLab.ThreadParallelEngine-3.2.dll" .\plugins
