Index: branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/Allele.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequency.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -37,5 +37,5 @@
   [Item("AlleleFrequencyAnalyzer", "An operator for analyzing the frequency of alleles.")]
   [StorableClass]
-  public abstract class AlleleFrequencyAnalyzer<T> : SingleSuccessorOperator, IAnalyzer where T : class, IItem {
+  public abstract class AlleleFrequencyAnalyzer<T> : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator where T : class, IItem {
     public virtual bool EnabledByDefault {
       get { return false; }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollection.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/AlleleFrequencyAnalysis/AlleleFrequencyCollectionHistory.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/BestScopeSolutionAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -36,9 +37,9 @@
   [Item("BestScopeSolutionAnalyzer", "An operator that extracts the scope containing the best quality.")]
   [StorableClass]
-  public class BestScopeSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer {
+  public class BestScopeSolutionAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
+
     public virtual bool EnabledByDefault {
       get { return true; }
     }
-
     public LookupParameter<BoolValue> MaximizationParameter {
       get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
@@ -47,9 +48,6 @@
       get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
     }
-    public ILookupParameter<IScope> BestSolutionParameter {
-      get { return (ILookupParameter<IScope>)Parameters["BestSolution"]; }
-    }
-    public ILookupParameter<IScope> BestKnownSolutionParameter {
-      get { return (ILookupParameter<IScope>)Parameters["BestKnownSolution"]; }
+    public IFixedValueParameter<StringValue> BestSolutionResultNameParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters["BestSolution ResultName"]; }
     }
     public ILookupParameter<DoubleValue> BestKnownQualityParameter {
@@ -58,4 +56,9 @@
     public IValueLookupParameter<ResultCollection> ResultsParameter {
       get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+
+    public string BestSolutionResultName {
+      get { return BestSolutionResultNameParameter.Value.Value; }
+      set { BestSolutionResultNameParameter.Value.Value = value; }
     }
 
@@ -67,4 +70,15 @@
       return new BestScopeSolutionAnalyzer(this, cloner);
     }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey("BestSolution ResultName"))
+        Parameters.Add(new FixedValueParameter<StringValue>("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution")));
+      if (Parameters.ContainsKey("BestSolution")) Parameters.Remove("BestSolution");
+      if (Parameters.ContainsKey("BestKnownSolution")) Parameters.Remove("BestKnownSolution");
+      #endregion
+    }
     #endregion
     public BestScopeSolutionAnalyzer()
@@ -72,6 +86,5 @@
       Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions."));
-      Parameters.Add(new LookupParameter<IScope>("BestSolution", "The best solution."));
-      Parameters.Add(new LookupParameter<IScope>("BestKnownSolution", "The best known solution."));
+      Parameters.Add(new FixedValueParameter<StringValue>("BestSolution ResultName", "The name of the result for storing the best solution.", new StringValue("Best Solution")));
       Parameters.Add(new LookupParameter<DoubleValue>("BestKnownQuality", "The quality of the best known solution."));
       Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the solution should be stored."));
@@ -84,4 +97,8 @@
       DoubleValue bestKnownQuality = BestKnownQualityParameter.ActualValue;
 
+      if (results.ContainsKey(BestSolutionResultName) && !typeof(IScope).IsAssignableFrom(results[BestSolutionResultName].DataType)) {
+        throw new InvalidOperationException(string.Format("Could not add best solution result, because there is already a result with the name \"{0}\" present in the result collection.", BestSolutionResultName));
+      }
+
       int i = -1;
       if (!max)
@@ -91,5 +108,5 @@
       IEnumerable<IScope> scopes = new IScope[] { ExecutionContext.Scope };
       for (int j = 0; j < QualityParameter.Depth; j++)
-        scopes = scopes.Select(x => (IEnumerable<IScope>)x.SubScopes).Aggregate((a, b) => a.Concat(b));
+        scopes = scopes.SelectMany(x => x.SubScopes);
       IScope currentBestScope = scopes.ToList()[i];
 
@@ -98,25 +115,31 @@
           || !max && qualities[i].Value < bestKnownQuality.Value) {
         BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[i].Value);
-        BestKnownSolutionParameter.ActualValue = (IScope)currentBestScope.Clone();
       }
 
-      IScope solution = BestSolutionParameter.ActualValue;
-      if (solution == null) {
-        solution = (IScope)currentBestScope.Clone();
-        BestSolutionParameter.ActualValue = solution;
-        results.Add(new Result("Best Solution", solution));
+      if (!results.ContainsKey(BestSolutionResultName)) {
+        var cloner = new Cloner();
+        //avoid cloning of subscopes and the results collection that the solution is put in
+        cloner.RegisterClonedObject(results, new ResultCollection());
+        cloner.RegisterClonedObject(currentBestScope.SubScopes, new ScopeList());
+        var solution = cloner.Clone(currentBestScope);
+
+        results.Add(new Result(BestSolutionResultName, solution));
       } else {
+        var bestSolution = (IScope)results[BestSolutionResultName].Value;
         string qualityName = QualityParameter.TranslatedName;
-        if (solution.Variables.ContainsKey(qualityName)) {
-          double bestSoFarQuality = (solution.Variables[qualityName].Value as DoubleValue).Value;
-          if (max && qualities[i].Value > bestSoFarQuality
-            || !max && qualities[i].Value < bestSoFarQuality) {
-            solution = (IScope)currentBestScope.Clone();
-            BestSolutionParameter.ActualValue = solution;
-            results["Best Solution"].Value = solution;
+        if (bestSolution.Variables.ContainsKey(qualityName)) {
+          double bestQuality = ((DoubleValue)bestSolution.Variables[qualityName].Value).Value;
+          if (max && qualities[i].Value > bestQuality
+              || !max && qualities[i].Value < bestQuality) {
+            var cloner = new Cloner();
+            //avoid cloning of subscopes and the results collection that the solution is put in
+            cloner.RegisterClonedObject(results, new ResultCollection());
+            cloner.RegisterClonedObject(currentBestScope.SubScopes, new ScopeList());
+            var solution = cloner.Clone(currentBestScope);
+
+            results[BestSolutionResultName].Value = solution;
           }
         }
       }
-
       return base.Apply();
     }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRow.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -76,4 +76,5 @@
       this.values = new ObservableList<double>(original.values);
     }
+    public DataRow() : this("DataRow") { }
     public DataRow(string name)
       : base(name) {
@@ -116,4 +117,8 @@
       OnVisualPropertiesChanged();
     }
+    protected override void OnNameChanged() {
+      base.OnNameChanged();
+      VisualProperties.DisplayName = Name;
+    }
   }
 }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataRowVisualProperties.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTable.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableHistory.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableValuesCollector.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/DataTableVisualProperties.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMap.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/HeatMapHistory.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlot.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRow.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotDataRowVisualProperties.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotHistory.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/DataVisualization/ScatterPlotVisualProperties.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/HeuristicLab.Analysis-3.3.csproj	(revision 12969)
@@ -11,5 +11,5 @@
     <RootNamespace>HeuristicLab.Analysis</RootNamespace>
     <AssemblyName>HeuristicLab.Analysis-3.3</AssemblyName>
-    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <TargetFrameworkProfile>
     </TargetFrameworkProfile>
@@ -46,4 +46,5 @@
     <WarningLevel>4</WarningLevel>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -57,4 +58,5 @@
     </DocumentationFile>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
@@ -66,4 +68,5 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
@@ -77,4 +80,5 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
@@ -86,4 +90,5 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
@@ -97,4 +102,5 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
@@ -142,6 +148,7 @@
     <Compile Include="MultiObjective\ParetoFrontAnalyzer.cs" />
     <Compile Include="Plugin.cs" />
-    <Compile Include="PopulationDiversityAnalysis\PopulationDiversityAnalyzer.cs" />
-    <Compile Include="PopulationDiversityAnalysis\SingleObjectivePopulationDiversityAnalyzer.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\PopulationDiversityAnalyzer.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\PopulationSimilarityAnalyzer.cs" />
+    <Compile Include="PopulationSimilarityAnalysis\SingleObjectivePopulationDiversityAnalyzer.cs" />
     <Compile Include="QualityAnalysis\BestAverageWorstQualityAnalyzer.cs" />
     <Compile Include="QualityAnalysis\BestAverageWorstQualityCalculator.cs" />
@@ -153,4 +160,14 @@
     <Compile Include="QualityAnalysis\QualityDistributionAnalyzer.cs" />
     <Compile Include="QualityAnalysis\ScaledQualityDifferenceAnalyzer.cs" />
+    <Compile Include="Statistics\BonferroniHolm.cs" />
+    <Compile Include="Statistics\EnumerableStatisticsExtension.cs" />
+    <Compile Include="Statistics\Fitting\ExpFitting.cs" />
+    <Compile Include="Statistics\Fitting\IFitting.cs" />
+    <Compile Include="Statistics\KruskalWallisTest.cs" />
+    <Compile Include="Statistics\Fitting\LinearLeastSquaresFitting.cs" />
+    <Compile Include="Statistics\Fitting\LogFitting.cs" />
+    <Compile Include="Statistics\KernelDensityEstimator.cs" />
+    <Compile Include="Statistics\PairwiseTest.cs" />
+    <Compile Include="Statistics\SampleSizeDetermination.cs" />
     <Compile Include="ValueAnalysis\SingleValueAnalyzer.cs" />
     <Compile Include="ValueAnalysis\MinAverageMaxValueAnalyzer.cs" />
@@ -236,4 +253,5 @@
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
@@ -245,5 +263,5 @@
   -->
   <PropertyGroup>
-   <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
 set ProjectDir=$(ProjectDir)
 set SolutionDir=$(SolutionDir)
@@ -252,5 +270,5 @@
 call PreBuildEvent.cmd
 </PreBuildEvent>
-<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
 export ProjectDir=$(ProjectDir)
 export SolutionDir=$(SolutionDir)
Index: branches/gteufl/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/MultiAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -69,5 +69,5 @@
     }
 
-    public override IOperation Apply() {
+    public override IOperation InstrumentedApply() {
       IntValue interval = UpdateIntervalParameter.ActualValue;
       if (interval == null) interval = new IntValue(1);
@@ -84,8 +84,8 @@
         foreach (IndexedItem<IAnalyzer> item in Operators.CheckedItems)
           next.Add(ExecutionContext.CreateOperation(item.Value));
-        next.Add(base.Apply());
+        next.Add(base.InstrumentedApply());
         return next;
       } else {
-        return base.Apply();
+        return base.InstrumentedApply();
       }
     }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/ParetoFrontAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -31,5 +31,5 @@
   [Item("ParetoFrontAnalyzer", "Analyzer for multiobjective problems that collects and presents the current Pareto front as double matrix as well as the solution scopes that lie on the current front.")]
   [StorableClass]
-  public abstract class ParetoFrontAnalyzer : SingleSuccessorOperator, IAnalyzer {
+  public abstract class ParetoFrontAnalyzer : SingleSuccessorOperator, IAnalyzer, IMultiObjectiveOperator {
     public virtual bool EnabledByDefault {
       get { return true; }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/MultiObjective/RankBasedParetoFrontAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Plugin.cs.frame
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Plugin.cs.frame	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,5 +26,5 @@
   /// Plugin class for HeuristicLab.Analysis plugin.
   /// </summary>
-  [Plugin("HeuristicLab.Analysis", "3.3.9.$WCREV$")]
+  [Plugin("HeuristicLab.Analysis", "3.3.12.$WCREV$")]
   [PluginFile("HeuristicLab.Analysis-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationDiversityAnalyzer.cs	(revision 12969)
@@ -0,0 +1,252 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  // use HeuristicLab.Analysis.SingleObjectivePopulationDiversityAnalyzer instead
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An operator for analyzing the solution diversity in a population.
+  /// </summary>
+  [Obsolete]
+  [Item("PopulationDiversityAnalyzer", "An operator for analyzing the solution diversity in a population.")]
+  [StorableClass]
+  public abstract class PopulationDiversityAnalyzer<T> : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator where T : class, IItem {
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+
+    public LookupParameter<BoolValue> MaximizationParameter {
+      get { return (LookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<T> SolutionParameter {
+      get { return (ScopeTreeLookupParameter<T>)Parameters["Solution"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public ValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (ValueParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public LookupParameter<IntValue> UpdateCounterParameter {
+      get { return (LookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+
+    [StorableConstructor]
+    protected PopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected PopulationDiversityAnalyzer(PopulationDiversityAnalyzer<T> original, Cloner cloner) : base(original, cloner) { }
+    public PopulationDiversityAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem."));
+      Parameters.Add(new ScopeTreeLookupParameter<T>("Solution", "The solutions whose diversity should be analyzed."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The qualities of the solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new ValueParameter<BoolValue>("StoreHistory", "True if the history of the population diversity analysis should be stored.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>("UpdateInterval", "The interval in which the population diversity analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the operator was called since the last update.", "PopulationDiversityAnalyzerUpdateCounter"));
+
+      MaximizationParameter.Hidden = true;
+      SolutionParameter.Hidden = true;
+      QualityParameter.Hidden = true;
+      ResultsParameter.Hidden = true;
+      UpdateCounterParameter.Hidden = true;
+    }
+
+    public override IOperation Apply() {
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+      // if counter does not yet exist then initialize it with update interval 
+      // to make sure the solutions are analyzed on the first application of this operator
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
+      } else updateCounter.Value++;
+
+      //analyze solutions only every 'updateInterval' times
+      if (updateCounter.Value == updateInterval) {
+        updateCounter.Value = 0;
+
+        bool max = MaximizationParameter.ActualValue.Value;
+        ItemArray<T> solutions = SolutionParameter.ActualValue;
+        ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+        bool storeHistory = StoreHistoryParameter.Value.Value;
+        int count = solutions.Length;
+
+        if (count > 1) {
+          // sort solutions by quality
+          T[] sortedSolutions = null;
+          if (max)
+            sortedSolutions = solutions
+              .Select((x, index) => new { Solution = x, Quality = qualities[index] })
+              .OrderByDescending(x => x.Quality)
+              .Select(x => x.Solution)
+              .ToArray();
+          else
+            sortedSolutions = solutions
+              .Select((x, index) => new { Solution = x, Quality = qualities[index] })
+              .OrderBy(x => x.Quality)
+              .Select(x => x.Solution)
+              .ToArray();
+
+          // calculate solution similarities
+          double[,] similarities = CalculateSimilarities(sortedSolutions);
+
+          // calculate minimum, average and maximum similarities
+          double similarity;
+          double[] minSimilarities = new double[count];
+          double[] avgSimilarities = new double[count];
+          double[] maxSimilarities = new double[count];
+          for (int i = 0; i < count; i++) {
+            minSimilarities[i] = 1;
+            avgSimilarities[i] = 0;
+            maxSimilarities[i] = 0;
+            for (int j = 0; j < count; j++) {
+              if (i != j) {
+                similarity = similarities[i, j];
+
+                if ((similarity < 0) || (similarity > 1))
+                  throw new InvalidOperationException("Solution similarities have to be in the interval [0;1].");
+
+                if (minSimilarities[i] > similarity) minSimilarities[i] = similarity;
+                avgSimilarities[i] += similarity;
+                if (maxSimilarities[i] < similarity) maxSimilarities[i] = similarity;
+              }
+            }
+            avgSimilarities[i] = avgSimilarities[i] / (count - 1);
+          }
+          double avgMinSimilarity = minSimilarities.Average();
+          double avgAvgSimilarity = avgSimilarities.Average();
+          double avgMaxSimilarity = maxSimilarities.Average();
+
+          // fetch results collection
+          ResultCollection results;
+          if (!ResultsParameter.ActualValue.ContainsKey(Name + " Results")) {
+            results = new ResultCollection();
+            ResultsParameter.ActualValue.Add(new Result(Name + " Results", results));
+          } else {
+            results = (ResultCollection)ResultsParameter.ActualValue[Name + " Results"].Value;
+          }
+
+          // store similarities
+          HeatMap similaritiesHeatMap = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
+          if (!results.ContainsKey("Solution Similarities"))
+            results.Add(new Result("Solution Similarities", similaritiesHeatMap));
+          else
+            results["Solution Similarities"].Value = similaritiesHeatMap;
+
+          // store similarities history
+          if (storeHistory) {
+            if (!results.ContainsKey("Solution Similarities History")) {
+              HeatMapHistory history = new HeatMapHistory();
+              history.Add(similaritiesHeatMap);
+              results.Add(new Result("Solution Similarities History", history));
+            } else {
+              ((HeatMapHistory)results["Solution Similarities History"].Value).Add(similaritiesHeatMap);
+            }
+          }
+
+          // store average minimum, average and maximum similarity
+          if (!results.ContainsKey("Average Minimum Solution Similarity"))
+            results.Add(new Result("Average Minimum Solution Similarity", new DoubleValue(avgMinSimilarity)));
+          else
+            ((DoubleValue)results["Average Minimum Solution Similarity"].Value).Value = avgMinSimilarity;
+
+          if (!results.ContainsKey("Average Average Solution Similarity"))
+            results.Add(new Result("Average Average Solution Similarity", new DoubleValue(avgAvgSimilarity)));
+          else
+            ((DoubleValue)results["Average Average Solution Similarity"].Value).Value = avgAvgSimilarity;
+
+          if (!results.ContainsKey("Average Maximum Solution Similarity"))
+            results.Add(new Result("Average Maximum Solution Similarity", new DoubleValue(avgMaxSimilarity)));
+          else
+            ((DoubleValue)results["Average Maximum Solution Similarity"].Value).Value = avgMaxSimilarity;
+
+          // store average minimum, average and maximum solution similarity data table
+          DataTable minAvgMaxSimilarityDataTable;
+          if (!results.ContainsKey("Average Minimum/Average/Maximum Solution Similarity")) {
+            minAvgMaxSimilarityDataTable = new DataTable("Average Minimum/Average/Maximum Solution Similarity");
+            minAvgMaxSimilarityDataTable.VisualProperties.XAxisTitle = "Iteration";
+            minAvgMaxSimilarityDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Minimum Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].VisualProperties.StartIndexZero = true;
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Average Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].VisualProperties.StartIndexZero = true;
+            minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Maximum Solution Similarity", null));
+            minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].VisualProperties.StartIndexZero = true;
+            results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
+          } else {
+            minAvgMaxSimilarityDataTable = (DataTable)results["Average Minimum/Average/Maximum Solution Similarity"].Value;
+          }
+          minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].Values.Add(avgMinSimilarity);
+          minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].Values.Add(avgAvgSimilarity);
+          minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].Values.Add(avgMaxSimilarity);
+
+          // store minimum, average, maximum similarities data table
+          DataTable minAvgMaxSimilaritiesDataTable = new DataTable("Minimum/Average/Maximum Solution Similarities");
+          minAvgMaxSimilaritiesDataTable.VisualProperties.XAxisTitle = "Solution Index";
+          minAvgMaxSimilaritiesDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Minimum Solution Similarity", null, minSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Minimum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Average Solution Similarity", null, avgSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Average Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Maximum Solution Similarity", null, maxSimilarities));
+          minAvgMaxSimilaritiesDataTable.Rows["Maximum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+          if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities")) {
+            results.Add(new Result("Minimum/Average/Maximum Solution Similarities", minAvgMaxSimilaritiesDataTable));
+          } else {
+            results["Minimum/Average/Maximum Solution Similarities"].Value = minAvgMaxSimilaritiesDataTable;
+          }
+
+          // store minimum, average, maximum similarities history
+          if (storeHistory) {
+            if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities History")) {
+              DataTableHistory history = new DataTableHistory();
+              history.Add(minAvgMaxSimilaritiesDataTable);
+              results.Add(new Result("Minimum/Average/Maximum Solution Similarities History", history));
+            } else {
+              ((DataTableHistory)results["Minimum/Average/Maximum Solution Similarities History"].Value).Add(minAvgMaxSimilaritiesDataTable);
+            }
+          }
+        }
+      }
+      return base.Apply();
+    }
+
+    protected abstract double[,] CalculateSimilarities(T[] solutions);
+  }
+  #endregion
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/PopulationSimilarityAnalyzer.cs	(revision 12969)
@@ -0,0 +1,267 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Analysis {
+  /// <summary>
+  /// An operator for analyzing the solution similarity in a population.
+  /// </summary>
+  [Item("PopulationSimilarityAnalyzer", "An operator for analyzing the solution similarity in a population.")]
+  [StorableClass]
+  public class PopulationSimilarityAnalyzer : SingleSuccessorOperator, IAnalyzer, ISimilarityBasedOperator {
+    private const string DiversityResultNameParameterName = "DiversityResultsName";
+
+    #region Backwards compatible code, remove with 3.4
+    private ISolutionSimilarityCalculator oldSimilarityCalculator;
+    [Storable(AllowOneWay = true, Name = "SimilarityCalculator")]
+    [Obsolete]
+    private ISolutionSimilarityCalculator SimilarityCalculator { set { oldSimilarityCalculator = value; } }
+    #endregion
+
+    public virtual bool EnabledByDefault {
+      get { return false; }
+    }
+    public ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (IValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public IConstrainedValueParameter<ISolutionSimilarityCalculator> SimilarityCalculatorParameter {
+      get { return (IConstrainedValueParameter<ISolutionSimilarityCalculator>)Parameters["SimilarityCalculator"]; }
+    }
+    public IValueParameter<BoolValue> StoreHistoryParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["StoreHistory"]; }
+    }
+    public IValueParameter<IntValue> UpdateIntervalParameter {
+      get { return (IValueParameter<IntValue>)Parameters["UpdateInterval"]; }
+    }
+    public ILookupParameter<IntValue> UpdateCounterParameter {
+      get { return (ILookupParameter<IntValue>)Parameters["UpdateCounter"]; }
+    }
+    public IFixedValueParameter<StringValue> DiversityResultNameParameter {
+      get { return (FixedValueParameter<StringValue>)Parameters[DiversityResultNameParameterName]; }
+    }
+
+    public string DiversityResultName {
+      get { return DiversityResultNameParameter.Value.Value; }
+      set { DiversityResultNameParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected PopulationSimilarityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected PopulationSimilarityAnalyzer(PopulationSimilarityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public PopulationSimilarityAnalyzer(IEnumerable<ISolutionSimilarityCalculator> validSimilarityCalculators)
+      : base() {
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope that contains the solutions which should be analyzed."));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", "The result collection where the population diversity analysis results should be stored."));
+      Parameters.Add(new ConstrainedValueParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate population similarity."));
+      Parameters.Add(new ValueParameter<BoolValue>("StoreHistory", "True if the history of the population diversity analysis should be stored.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>("UpdateInterval", "The interval in which the population diversity analysis should be applied.", new IntValue(1)));
+      Parameters.Add(new LookupParameter<IntValue>("UpdateCounter", "The value which counts how many times the operator was called since the last update.", "PopulationDiversityAnalyzerUpdateCounter"));
+      Parameters.Add(new FixedValueParameter<StringValue>(DiversityResultNameParameterName, "Specifies how the diversity results should be named.", new StringValue("PopulationDiversity")));
+
+      var similarityCalculators = SimilarityCalculatorParameter.ValidValues;
+      foreach (var sc in validSimilarityCalculators)
+        similarityCalculators.Add(sc);
+
+
+      ResultsParameter.Hidden = true;
+      UpdateCounterParameter.Hidden = true;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PopulationSimilarityAnalyzer(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.3
+      #region Backwards compatible code, remove with 3.4
+      if (!Parameters.ContainsKey(DiversityResultNameParameterName))
+        Parameters.Add(new FixedValueParameter<StringValue>(DiversityResultNameParameterName, "Specifies how the diversity results should be named.", new StringValue("PopulationDiversity")));
+
+      if (!Parameters.ContainsKey("SimilarityCalculator"))
+        Parameters.Add(new ConstrainedValueParameter<ISolutionSimilarityCalculator>("SimilarityCalculator", "The similarity calculator that should be used to calculate solution similarity."));
+
+      SimilarityCalculatorParameter.ValidValues.Add(oldSimilarityCalculator);
+      #endregion
+    }
+
+    public override IOperation Apply() {
+      int updateInterval = UpdateIntervalParameter.Value.Value;
+      IntValue updateCounter = UpdateCounterParameter.ActualValue;
+      // if counter does not yet exist then initialize it with update interval
+      // to make sure the solutions are analyzed on the first application of this operator
+      if (updateCounter == null) {
+        updateCounter = new IntValue(updateInterval);
+        UpdateCounterParameter.ActualValue = updateCounter;
+      }
+      //analyze solutions only every 'updateInterval' times
+      if (updateCounter.Value != updateInterval) {
+        updateCounter.Value++;
+        return base.Apply();
+      }
+      updateCounter.Value = 1;
+
+      bool storeHistory = StoreHistoryParameter.Value.Value;
+      int count = CurrentScopeParameter.ActualValue.SubScopes.Count;
+
+      if (count > 1) {
+        var similarityCalculator = SimilarityCalculatorParameter.Value;
+        // calculate solution similarities
+        var similarityMatrix = similarityCalculator.CalculateSolutionCrowdSimilarity(CurrentScopeParameter.ActualValue);
+        double[,] similarities = new double[similarityMatrix.Length, similarityMatrix[0].Length];
+        for (int i = 0; i < similarityMatrix.Length; i++)
+          for (int j = 0; j < similarityMatrix[0].Length; j++)
+            similarities[i, j] = similarityMatrix[i][j];
+
+        // calculate minimum, average and maximum similarities
+        double similarity;
+        double[] minSimilarities = new double[count];
+        double[] avgSimilarities = new double[count];
+        double[] maxSimilarities = new double[count];
+        for (int i = 0; i < count; i++) {
+          minSimilarities[i] = 1;
+          avgSimilarities[i] = 0;
+          maxSimilarities[i] = 0;
+          for (int j = 0; j < count; j++) {
+            if (i != j) {
+              similarity = similarities[i, j];
+
+              if ((similarity < 0) || (similarity > 1))
+                throw new InvalidOperationException("Solution similarities have to be in the interval [0;1].");
+
+              if (minSimilarities[i] > similarity) minSimilarities[i] = similarity;
+              avgSimilarities[i] += similarity;
+              if (maxSimilarities[i] < similarity) maxSimilarities[i] = similarity;
+            }
+          }
+          avgSimilarities[i] = avgSimilarities[i] / (count - 1);
+        }
+        double avgMinSimilarity = minSimilarities.Average();
+        double avgAvgSimilarity = avgSimilarities.Average();
+        double avgMaxSimilarity = maxSimilarities.Average();
+
+        // fetch results collection
+        ResultCollection results;
+        if (!ResultsParameter.ActualValue.ContainsKey(DiversityResultName)) {
+          results = new ResultCollection();
+          ResultsParameter.ActualValue.Add(new Result(DiversityResultName, results));
+        } else {
+          results = (ResultCollection)ResultsParameter.ActualValue[DiversityResultName].Value;
+        }
+
+        // store similarities
+        HeatMap similaritiesHeatMap = new HeatMap(similarities, "Solution Similarities", 0.0, 1.0);
+        if (!results.ContainsKey("Solution Similarities"))
+          results.Add(new Result("Solution Similarities", similaritiesHeatMap));
+        else
+          results["Solution Similarities"].Value = similaritiesHeatMap;
+
+        // store similarities history
+        if (storeHistory) {
+          if (!results.ContainsKey("Solution Similarities History")) {
+            HeatMapHistory history = new HeatMapHistory();
+            history.Add(similaritiesHeatMap);
+            results.Add(new Result("Solution Similarities History", history));
+          } else {
+            ((HeatMapHistory)results["Solution Similarities History"].Value).Add(similaritiesHeatMap);
+          }
+        }
+
+        // store average minimum, average and maximum similarity
+        if (!results.ContainsKey("Average Minimum Solution Similarity"))
+          results.Add(new Result("Average Minimum Solution Similarity", new DoubleValue(avgMinSimilarity)));
+        else
+          ((DoubleValue)results["Average Minimum Solution Similarity"].Value).Value = avgMinSimilarity;
+
+        if (!results.ContainsKey("Average Average Solution Similarity"))
+          results.Add(new Result("Average Average Solution Similarity", new DoubleValue(avgAvgSimilarity)));
+        else
+          ((DoubleValue)results["Average Average Solution Similarity"].Value).Value = avgAvgSimilarity;
+
+        if (!results.ContainsKey("Average Maximum Solution Similarity"))
+          results.Add(new Result("Average Maximum Solution Similarity", new DoubleValue(avgMaxSimilarity)));
+        else
+          ((DoubleValue)results["Average Maximum Solution Similarity"].Value).Value = avgMaxSimilarity;
+
+        // store average minimum, average and maximum solution similarity data table
+        DataTable minAvgMaxSimilarityDataTable;
+        if (!results.ContainsKey("Average Minimum/Average/Maximum Solution Similarity")) {
+          minAvgMaxSimilarityDataTable = new DataTable("Average Minimum/Average/Maximum Solution Similarity");
+          minAvgMaxSimilarityDataTable.VisualProperties.XAxisTitle = "Iteration";
+          minAvgMaxSimilarityDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Minimum Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].VisualProperties.StartIndexZero = true;
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Average Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].VisualProperties.StartIndexZero = true;
+          minAvgMaxSimilarityDataTable.Rows.Add(new DataRow("Average Maximum Solution Similarity", null));
+          minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].VisualProperties.StartIndexZero = true;
+          results.Add(new Result("Average Minimum/Average/Maximum Solution Similarity", minAvgMaxSimilarityDataTable));
+        } else {
+          minAvgMaxSimilarityDataTable = (DataTable)results["Average Minimum/Average/Maximum Solution Similarity"].Value;
+        }
+        minAvgMaxSimilarityDataTable.Rows["Average Minimum Solution Similarity"].Values.Add(avgMinSimilarity);
+        minAvgMaxSimilarityDataTable.Rows["Average Average Solution Similarity"].Values.Add(avgAvgSimilarity);
+        minAvgMaxSimilarityDataTable.Rows["Average Maximum Solution Similarity"].Values.Add(avgMaxSimilarity);
+
+        // store minimum, average, maximum similarities data table
+        DataTable minAvgMaxSimilaritiesDataTable = new DataTable("Minimum/Average/Maximum Solution Similarities");
+        minAvgMaxSimilaritiesDataTable.VisualProperties.XAxisTitle = "Solution Index";
+        minAvgMaxSimilaritiesDataTable.VisualProperties.YAxisTitle = "Solution Similarity";
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Minimum Solution Similarity", null, minSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Minimum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Average Solution Similarity", null, avgSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Average Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        minAvgMaxSimilaritiesDataTable.Rows.Add(new DataRow("Maximum Solution Similarity", null, maxSimilarities));
+        minAvgMaxSimilaritiesDataTable.Rows["Maximum Solution Similarity"].VisualProperties.ChartType = DataRowVisualProperties.DataRowChartType.Points;
+        if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities")) {
+          results.Add(new Result("Minimum/Average/Maximum Solution Similarities", minAvgMaxSimilaritiesDataTable));
+        } else {
+          results["Minimum/Average/Maximum Solution Similarities"].Value = minAvgMaxSimilaritiesDataTable;
+        }
+
+        // store minimum, average, maximum similarities history
+        if (storeHistory) {
+          if (!results.ContainsKey("Minimum/Average/Maximum Solution Similarities History")) {
+            DataTableHistory history = new DataTableHistory();
+            history.Add(minAvgMaxSimilaritiesDataTable);
+            results.Add(new Result("Minimum/Average/Maximum Solution Similarities History", history));
+          } else {
+            ((DataTableHistory)results["Minimum/Average/Maximum Solution Similarities History"].Value).Add(minAvgMaxSimilaritiesDataTable);
+          }
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/PopulationSimilarityAnalysis/SingleObjectivePopulationDiversityAnalyzer.cs	(revision 12969)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Analysis {
+  // use HeuristicLab.Analysis.PopulationSimilarityAnalyzer instead
+  // BackwardsCompatibility3.3
+  #region Backwards compatible code, remove with 3.4
+  /// <summary>
+  /// An operator for analyzing the solution diversity in a population.
+  /// </summary>
+  [Obsolete]
+  [NonDiscoverableType]
+  [Item("SingleObjectivePopulationDiversityAnalyzer", "An operator for analyzing the solution diversity in a population.")]
+  [StorableClass]
+  public class SingleObjectivePopulationDiversityAnalyzer : PopulationSimilarityAnalyzer {
+    [StorableConstructor]
+    protected SingleObjectivePopulationDiversityAnalyzer(bool deserializing) : base(deserializing) { }
+    protected SingleObjectivePopulationDiversityAnalyzer(SingleObjectivePopulationDiversityAnalyzer original, Cloner cloner) : base(original, cloner) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectivePopulationDiversityAnalyzer(this, cloner);
+    }
+  }
+  #endregion
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Properties/AssemblyInfo.cs.frame	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -32,5 +32,5 @@
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("HeuristicLab")]
-[assembly: AssemblyCopyright("(c) 2002-2013 HEAL")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -54,3 +54,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.3.0.0")]
-[assembly: AssemblyFileVersion("3.3.9.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.12.$WCREV$")]
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -36,5 +36,5 @@
   [Item("BestAverageWorstQualityAnalyzer", "An operator which analyzes the best, average and worst quality of solutions in the scope tree.")]
   [StorableClass]
-  public sealed class BestAverageWorstQualityAnalyzer : AlgorithmOperator, IAnalyzer {
+  public sealed class BestAverageWorstQualityAnalyzer : AlgorithmOperator, IAnalyzer, ISingleObjectiveOperator {
     #region Parameter properties
     public ValueLookupParameter<BoolValue> MaximizationParameter {
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestAverageWorstQualityCalculator.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,4 +24,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -33,5 +34,5 @@
   [Item("BestAverageWorstQualityCalculator", "An operator which calculates the best, average and worst quality of solutions in the scope tree.")]
   [StorableClass]
-  public sealed class BestAverageWorstQualityCalculator : SingleSuccessorOperator {
+  public sealed class BestAverageWorstQualityCalculator : SingleSuccessorOperator, ISingleObjectiveOperator {
     public ValueLookupParameter<BoolValue> MaximizationParameter {
       get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/BestQualityMemorizer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -24,4 +24,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -33,5 +34,5 @@
   [Item("BestQualityMemorizer", "An operator that updates the best quality found so far with those qualities contained in the scope tree.")]
   [StorableClass]
-  public class BestQualityMemorizer : SingleSuccessorOperator {
+  public class BestQualityMemorizer : SingleSuccessorOperator, ISingleObjectiveOperator {
     public ValueLookupParameter<BoolValue> MaximizationParameter {
       get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -36,5 +36,5 @@
   [Item("QualityAnalyzer", "An operator which analyzes the quality of solutions in the scope tree.")]
   [StorableClass]
-  public sealed class QualityAnalyzer : AlgorithmOperator, IAnalyzer {
+  public sealed class QualityAnalyzer : AlgorithmOperator, IAnalyzer, ISingleObjectiveOperator {
     #region Parameter properties
     public ValueLookupParameter<BoolValue> MaximizationParameter {
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDifferenceCalculator.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/QualityDistributionAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -32,5 +32,5 @@
   [Item("QualityDistributionAnalyzer", "Analyzes the distribution of the quality values in that it adds a Histogram of them into the result collection.")]
   [StorableClass]
-  public class QualityDistributionAnalyzer : SingleSuccessorOperator, IAnalyzer, IIterationBasedOperator {
+  public class QualityDistributionAnalyzer : SingleSuccessorOperator, IAnalyzer, IIterationBasedOperator, ISingleObjectiveOperator {
 
     #region Parameter properties
Index: branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/QualityAnalysis/ScaledQualityDifferenceAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -33,5 +33,5 @@
 A value towards 0 always means that it's closer to the better fitness value, while a value towards 1 means that it's closer to the worse fitness value.")]
   [StorableClass]
-  public class ScaledQualityDifferenceAnalyzer : SingleSuccessorOperator, IAnalyzer {
+  public class ScaledQualityDifferenceAnalyzer : SingleSuccessorOperator, IAnalyzer, ISingleObjectiveOperator {
     public virtual bool EnabledByDefault {
       get { return true; }
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/BonferroniHolm.cs	(revision 12969)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class BonferroniHolm {
+    /// <summary>
+    /// Based on David Groppe's MATLAB implementation 
+    /// (BSD licensed, see 
+    /// http://www.mathworks.com/matlabcentral/fileexchange/28303-bonferroni-holm-correction-for-multiple-comparisons)
+    /// </summary>
+    public static double[] Calculate(double globalAlpha, double[] pValues, out bool[] h) {
+      int k = pValues.Length;
+      double[] alphaNiveau = new double[k];
+      double[] adjustedPValues = new double[k];
+      bool[] decision = new bool[k];
+      Dictionary<int, double> pValuesIndizes = new Dictionary<int, double>();
+
+      for (int i = 0; i < k; i++) {
+        pValuesIndizes.Add(i, pValues[i]);
+      }
+      var sortedPValues = pValuesIndizes.OrderBy(x => x.Value).ToArray();
+
+      for (int i = 1; i < k + 1; i++) {
+        alphaNiveau[i - 1] = globalAlpha / (k - i + 1);
+        int idx = sortedPValues[i - 1].Key;
+
+        if (i == 1) {
+          //true means reject
+          decision[idx] = sortedPValues[i - 1].Value < alphaNiveau[i - 1];
+          adjustedPValues[idx] = sortedPValues[i - 1].Value * (k - i + 1);
+        } else {
+          decision[idx] = decision[sortedPValues[i - 2].Key] && (sortedPValues[i - 1].Value < alphaNiveau[i - 1]);
+          adjustedPValues[idx] = Math.Max(adjustedPValues[sortedPValues[i - 2].Key], sortedPValues[i - 1].Value * (k - i + 1));
+        }
+        if (adjustedPValues[idx] > 1.0) {
+          adjustedPValues[idx] = 1.0;
+        }
+      }
+
+      h = decision;
+      return adjustedPValues;
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/EnumerableStatisticsExtension.cs	(revision 12969)
@@ -0,0 +1,48 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class EnumerableStatisticExtensions {
+    public static Tuple<double, double> ConfidenceIntervals(this IEnumerable<double> values, double alpha) {
+      return ConfidenceIntervals(values.ToArray(), alpha);
+    }
+
+    public static Tuple<double, double> ConfidenceIntervals(this double[] values, double alpha) {
+      double lower, upper;
+      int n = values.Length;
+      if (n <= 1) return new Tuple<double, double>(double.NaN, double.NaN);
+
+      double s = values.StandardDeviation();
+      double x = values.Average();
+      double t = alglib.invstudenttdistribution(n - 1, (1.0 - alpha) / 2.0);
+
+      lower = x + t * (s / Math.Sqrt(n));
+      upper = x - t * (s / Math.Sqrt(n));
+
+      return new Tuple<double, double>(lower, upper);
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/ExpFitting.cs	(revision 12969)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class ExpFitting : IFitting {
+    private void ExpFunc(double[] c, double[] x, ref double func, object obj) {
+      func = Math.Exp(-c[0] * Math.Pow(x[0], 2));
+    }
+
+    private double[] GetDefaultXValues(int n) {
+      var stdX = Enumerable.Range(1, n).Select(x => (double)x).ToArray();
+      return stdX;
+    }
+
+    public void Calculate(double[] dataPoints, out double p0) {
+      var stdX = GetDefaultXValues(dataPoints.Count());
+      Calculate(dataPoints, stdX, out p0);
+    }
+
+    public void Calculate(double[] y, double[] x, out double p0) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double[] c = new double[] { 0.3 };
+      double epsf = 0;
+      double epsx = 0.000001;
+      int maxits = 0;
+      int info;
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      double diffstep = 0.0001;
+      double[,] xx = new double[x.Count(), 1];
+
+      for (int i = 0; i < x.Count(); i++) {
+        xx[i, 0] = x[i];
+      }
+
+      alglib.lsfitcreatef(xx, y, c, diffstep, out state);
+      alglib.lsfitsetcond(state, epsf, epsx, maxits);
+      alglib.lsfitfit(state, ExpFunc, null, null);
+      alglib.lsfitresults(state, out info, out c, out rep);
+
+      p0 = c[0];
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double c0;
+      Calculate(dataPoints, out c0);
+      var stdX = GetDefaultXValues(dataPoints.Count());
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(Math.Exp(-c0 * Math.Pow(stdX[i], 2)));
+      }
+
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      DataRow newRow = new DataRow();
+      double c0;
+      Calculate(y, x, out c0);
+
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(Math.Exp(-c0 * Math.Pow(x[i], 2)));
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Exponential Fitting";
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/IFitting.cs	(revision 12969)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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
+
+namespace HeuristicLab.Analysis.Statistics {
+  public interface IFitting {
+    DataRow CalculateFittedLine(double[] dataPoints);
+    DataRow CalculateFittedLine(double[] y, double[] x);
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LinearLeastSquaresFitting.cs	(revision 12969)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class LinearLeastSquaresFitting : IFitting {
+    public void Calculate(double[] dataPoints, out double slope, out double intercept) {
+      var stdX = Enumerable.Range(0, dataPoints.Count()).Select(x => (double)x).ToArray();
+      Calculate(dataPoints, stdX, out slope, out intercept);
+    }
+
+    public void Calculate(double[] y, double[] x, out double slope, out double intercept) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double sxy = 0.0;
+      double sxx = 0.0;
+      int n = y.Count();
+      double sy = y.Sum();
+      double sx = ((n - 1) * n) / 2.0;
+      double avgy = sy / n;
+      double avgx = sx / n;
+
+      for (int i = 0; i < n; i++) {
+        sxy += x[i] * y[i];
+        sxx += x[i] * x[i];
+      }
+
+      slope = (sxy - (n * avgx * avgy)) / (sxx - (n * avgx * avgx));
+      intercept = avgy - slope * avgx;
+    }
+
+    public double CalculateError(double[] dataPoints, double slope, double intercept) {
+      double r;
+      double avgy = dataPoints.Average();
+      double sstot = 0.0;
+      double sserr = 0.0;
+
+      for (int i = 0; i < dataPoints.Count(); i++) {
+        double y = slope * i + intercept;
+        sstot += Math.Pow(dataPoints[i] - avgy, 2);
+        sserr += Math.Pow(dataPoints[i] - y, 2);
+      }
+
+      r = 1.0 - (sserr / sstot);
+      return r;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      double slope, intercept;
+      Calculate(y, x, out slope, out intercept);
+
+      DataRow newRow = new DataRow();
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(slope * x[i] + intercept);
+      }
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double slope, intercept;
+      Calculate(dataPoints, out slope, out intercept);
+      var stdX = Enumerable.Range(0, dataPoints.Count()).Select(x => (double)x).ToArray();
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(slope * stdX[i] + intercept);
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Linear Fitting";
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/Fitting/LogFitting.cs	(revision 12969)
@@ -0,0 +1,98 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class LogFitting : IFitting {
+    private void LogFunc(double[] c, double[] x, ref double func, object obj) {
+      func = c[0] * Math.Exp(c[1] / x[0]);
+    }
+
+    private double[] GetDefaultXValues(int n) {
+      var stdX = Enumerable.Range(1, n).Select(x => (double)x).ToArray();
+      return stdX;
+    }
+
+    public void Calculate(double[] dataPoints, out double p0, out double p1) {
+      var stdX = GetDefaultXValues(dataPoints.Count());
+      Calculate(dataPoints, stdX, out p0, out p1);
+    }
+
+    public void Calculate(double[] y, double[] x, out double p0, out double p1) {
+      if (y.Count() != x.Count()) {
+        throw new ArgumentException("The lenght of x and y needs do be equal. ");
+      }
+
+      double[] c = new double[] { 0.3, 0.3 };
+      double epsf = 0;
+      double epsx = 0.000001;
+      int maxits = 0;
+      int info;
+      alglib.lsfitstate state;
+      alglib.lsfitreport rep;
+      double diffstep = 0.0001;
+      double[,] xx = new double[x.Count(), 1];
+
+      for (int i = 0; i < x.Count(); i++) {
+        xx[i, 0] = x[i];
+      }
+
+      alglib.lsfitcreatef(xx, y, c, diffstep, out state);
+      alglib.lsfitsetcond(state, epsf, epsx, maxits);
+      alglib.lsfitfit(state, LogFunc, null, null);
+      alglib.lsfitresults(state, out info, out c, out rep);
+
+      p0 = c[0];
+      p1 = c[1];
+    }
+
+    public DataRow CalculateFittedLine(double[] dataPoints) {
+      DataRow newRow = new DataRow();
+      double c0, c1;
+      Calculate(dataPoints, out c0, out c1);
+      var stdX = GetDefaultXValues(dataPoints.Count());
+
+      for (int i = 0; i < stdX.Count(); i++) {
+        newRow.Values.Add(c0 * Math.Exp(c1 / stdX[i]));
+      }
+
+      return newRow;
+    }
+
+    public DataRow CalculateFittedLine(double[] y, double[] x) {
+      DataRow newRow = new DataRow();
+      double c0, c1;
+      Calculate(y, x, out c0, out c1);
+
+      for (int i = 0; i < x.Count(); i++) {
+        newRow.Values.Add(c0 * Math.Exp(c1 / x[i]));
+      }
+
+      return newRow;
+    }
+
+    public override string ToString() {
+      return "Logarithmic Fitting";
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KernelDensityEstimator.cs	(revision 12969)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class KernelDensityEstimator {
+    public static double[] Density(double[] x, double mean, double stdDev) {
+      return x.Select(xi => Density(xi, mean, stdDev)).ToArray();
+    }
+
+    public static double Density(double x, double mean, double stdDev) {
+      return (1.0 / (stdDev * Math.Sqrt(2.0 * Math.PI))) *
+                  Math.Exp(-((Math.Pow(x - mean, 2.0)) /
+                             (2.0 * Math.Pow(stdDev, 2.0))));
+    }
+
+    // the scale (sigma) of the kernel is a parameter
+    public static List<Tuple<double, double>> Density(double[] x, int nrOfPoints, double stepWidth, double sigma = 1.0) {
+      // calculate grid for which to estimate the density
+      double[] newX = new double[nrOfPoints];
+      double margin = stepWidth * 2;
+
+      double dataMin = x.Min() - margin;
+      double dataMax = x.Max() + margin;
+      double diff = (dataMax - dataMin) / nrOfPoints;
+      double cur = dataMin;
+      newX[0] = cur;
+      for (int i = 1; i < nrOfPoints; i++) {
+        cur += diff;
+        newX[i] = cur;
+      }
+
+      // for each of the points for which we want to calculate the density
+      // we sum up all the densities of the observed points assuming they are at the center of a normal distribution
+      var y = from xi in newX
+              select (from obsX in x
+                      select Density(xi, obsX, sigma)).Sum();
+
+      return newX.Zip(y, Tuple.Create).ToList();
+    }
+
+    //Silverman's rule of thumb for bandwidth estimation (sigma)
+    public static double EstimateBandwidth(double[] x) {
+      return 1.06 * x.StandardDeviation() * Math.Pow(x.Length, -0.2);
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/KruskalWallisTest.cs	(revision 12969)
@@ -0,0 +1,151 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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 HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class KruskalWallisTest {
+    /// <summary>
+    /// Performs the Kruskal-Wallis test and returns the p-Value. 
+    /// (source based on R's kruskal.test(), GNU GPL)
+    /// </summary>
+    public static double Test(double[][] data) {
+      double[] g;
+      double[] x = FlattenArray(data, out g);
+      int n = x.Length;
+      int parameter = data.Length - 1;
+
+      int[] r = Rank(x);
+      double[][] ties = CountDuplicates(x);
+      double statistic = CalculateStatistic(r, g);
+      double tiesCorrection = CalculateTiesCorrection(ties);
+      statistic = ((12 * statistic / (n * (n + 1)) - 3 * (n + 1)) /
+                  (1 - tiesCorrection / (Math.Pow(n, 3) - n)));
+
+      return alglib.chisquarecdistribution(parameter, statistic);
+    }
+
+    private static double CalculateStatistic(int[] r, double[] g) {
+      double result = 0.0;
+      double lastG = g[0];
+      double curSum = 0.0;
+      int cnt = 0;
+      for (int i = 0; i < r.Length; i++) {
+        if (lastG.IsAlmost(g[i])) {
+          curSum += r[i];
+          cnt++;
+        } else {
+          double sum = Math.Pow(curSum, 2);
+          sum /= cnt;
+          result += sum;
+
+          lastG = g[i];
+          curSum = r[i];
+          cnt = 1;
+        }
+      }
+
+      double lastSum = Math.Pow(curSum, 2);
+      lastSum /= cnt;
+      result += lastSum;
+
+      return result;
+    }
+
+    private static double CalculateTiesCorrection(double[][] ties) {
+      double sum = 0.0;
+      for (int i = 0; i < ties[1].Length; i++) {
+        double tic = Math.Pow(ties[1][i], 3) - ties[1][i];
+        sum += tic;
+      }
+      return sum;
+    }
+
+    private static double[] FlattenArray(double[][] x, out double[] indizes) {
+      int compLenght = 0;
+      for (int i = 0; i < x.Length; i++) {
+        compLenght += x[i].Length;
+      }
+
+      double[] result = new double[compLenght];
+      indizes = new double[compLenght];
+
+      int resultPos = 0;
+      for (int i = 0; i < x.Length; i++) {
+        Array.Copy(x[i], 0, result, resultPos, x[i].Length);
+
+        for (int j = resultPos; j < resultPos + x[i].Length; j++) {
+          indizes[j] = i;
+        }
+        resultPos += x[i].Length;
+      }
+
+      return result;
+    }
+
+    private static double[][] CountDuplicates(double[] x) {
+      List<double> number = new List<double>();
+      List<double> cnt = new List<double>();
+      double[] sortedX = new double[x.Length];
+
+      Array.Copy(x, sortedX, x.Length);
+      Array.Sort(sortedX);
+
+      double last = x[0];
+      number.Add(x[0]);
+      cnt.Add(1);
+
+      for (int i = 1; i < x.Length; i++) {
+        if (!last.IsAlmost(x[i])) {
+          number.Add(x[i]);
+          last = x[i];
+          cnt.Add(1);
+        } else {
+          cnt[cnt.Count - 1] += 1;
+        }
+      }
+
+      double[][] result = new double[2][];
+      result[0] = number.ToArray();
+      result[1] = cnt.ToArray();
+
+      return result;
+    }
+
+    private static int[] Rank(double[] x) {
+      double[] keys = new double[x.Length];
+      int[] items = new int[x.Length];
+      int[] ranks = new int[x.Length];
+
+      Array.Copy(x, keys, x.Length);
+      for (int i = 0; i < x.Length; i++) items[i] = i;
+
+      Array.Sort(keys, items);
+
+      for (int i = 0; i < x.Length; i++) {
+        ranks[items[i]] = i + 1;
+      }
+      return ranks;
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/PairwiseTest.cs	(revision 12969)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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
+
+
+namespace HeuristicLab.Analysis.Statistics {
+  public class PairwiseTest {
+    public static double TTest(double[] group1, double[] group2) {
+      double left, right, both;
+      alglib.unequalvariancettest(group1, group1.Length, group2, group2.Length, out both, out left, out right);
+      return both;
+    }
+
+    public static double MannWhitneyUTest(double[] group1, double[] group2) {
+      double mwuBothtails, mwuLefttail, mwuRighttail;
+      alglib.mannwhitneyutest(group1, group1.Length, group2, group2.Length, out mwuBothtails, out mwuLefttail, out mwuRighttail);
+      return mwuBothtails;
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 12969)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/Statistics/SampleSizeDetermination.cs	(revision 12969)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Analysis.Statistics {
+  public static class SampleSizeDetermination {
+    /// <summary>
+    /// Determines for a given sample the required sample size as described in 
+    /// Göran Kauermann, Helmut Küchenhoff: Stichproben: Methoden und praktische Umsetzung mit R, section 2.27. 
+    /// </summary>
+    /// <param name="samples">The pilot sample.</param>
+    /// <param name="conf">Confidence Interval.</param>
+    /// <returns>Number of required samples for the given confidence interval. </returns>
+    public static int DetermineSampleSizeByEstimatingMean(double[] samples, double conf = 0.95) {
+      if (conf < 0.0 || conf > 1.0) throw new ArgumentException("The confidence interval must be between zero and one.");
+
+      var confInterval = samples.ConfidenceIntervals(conf);
+      double e = (confInterval.Item2 - confInterval.Item1) / 2;
+      double s = samples.StandardDeviation();
+      double z = alglib.invnormaldistribution((conf + 1) / 2);
+      double n = samples.Count();
+
+      double result = Math.Pow(s, 2) / ((Math.Pow(e, 2) / Math.Pow(z, 2)) + (Math.Pow(s, 2) / n));
+
+      result = Math.Ceiling(result);
+      if (result > int.MaxValue)
+        return int.MaxValue;
+      else
+        return (int)result;
+    }
+
+    /// <summary>
+    /// Calculates Cohen's d.
+    /// </summary>
+    /// <returns>Cohen's d. 
+    /// d = 0.2 means small effect
+    /// d = 0.5 means medium effect
+    /// d = 0.8 means big effect
+    /// According to Wikipedia this means: "A lower Cohen's d indicates a necessity of larger sample sizes, and vice versa."
+    /// </returns>
+    public static double CalculateCohensD(double[] d1, double[] d2) {
+      double x1, x2, s1, s2;
+
+      x1 = d1.Average();
+      x2 = d2.Average();
+      s1 = d1.Variance();
+      s2 = d2.Variance();
+
+      return Math.Abs(x1 - x2) / Math.Sqrt((s1 + s2) / 2);
+    }
+
+    /// <summary>
+    /// Calculates Hedges' g. 
+    /// Hedges' g works like Cohen's d but corrects for bias. 
+    /// </summary>
+    /// <returns>Hedges' g</returns>
+    public static double CalculateHedgesG(double[] d1, double[] d2) {
+      double x1, x2, s1, s2, n1, n2, s, g, c;
+
+      x1 = d1.Average();
+      x2 = d2.Average();
+      s1 = d1.Variance();
+      s2 = d2.Variance();
+      n1 = d1.Count();
+      n2 = d2.Count();
+
+      s = Math.Sqrt(((n1 - 1) * s1 + (n2 - 1) * s2) / (n1 + n2 - 2));
+      g = Math.Abs(x1 - x2) / s;
+      c = (1 - (3 / (4 * (n1 + n2) - 9))) * g;
+
+      return c;
+    }
+  }
+}
Index: branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/MinAverageMaxValueCalculator.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/SingleValueAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs
===================================================================
--- branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 10225)
+++ branches/gteufl/HeuristicLab.Analysis/3.3/ValueAnalysis/ValueAnalyzer.cs	(revision 12969)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
