Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ArrayExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ArrayExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ArrayExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/AsyncHelper.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/AsyncHelper.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/AsyncHelper.cs	(revision 15973)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Runtime.ExceptionServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Common {
+  public static class AsyncHelper {
+    public static async Task DoAsync(Action<CancellationToken> startAction, CancellationToken cancellationToken) {
+      try {
+        await Task.Factory.StartNew(
+          ct => startAction((CancellationToken)ct),
+          cancellationToken,
+          cancellationToken,
+          TaskCreationOptions.DenyChildAttach | TaskCreationOptions.LongRunning,
+          TaskScheduler.Default);
+      } catch (OperationCanceledException) {
+      } catch (AggregateException ae) {
+        ae.FlattenAndHandle(new[] { typeof(OperationCanceledException) }, e => ExceptionDispatchInfo.Capture(e).Throw());
+      }
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/CancelEventArgs.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/CancelEventArgs.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/CancelEventArgs.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Cloner.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Cloner.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Cloner.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ColorGradient.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ColorGradient.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ColorGradient.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Constants.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Constants.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Constants.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/ContentManager.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/ContentManager.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/ContentManager.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IContent.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IContent.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IContent.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IStorableContent.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IStorableContent.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Content/IStorableContent.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DeepCloneable.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DeepCloneable.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DeepCloneable.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DoubleExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DoubleExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/DoubleExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EnumerableExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EnumerableExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EnumerableExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -98,4 +98,67 @@
       return sequences.Where(s => s.Any()).Aggregate(result, (current, s) => (from seq in current from item in s select seq.Concat(new[] { item })));
     }
+
+    /// <summary>
+    /// Compute all k-combinations of elements from the provided collection.
+    /// <param name="elements">The collection of elements</param>
+    /// <param name="k">The combination group size</param>
+    /// <returns>An enumerable sequence of all the possible k-combinations of elements</returns>
+    /// </summary>
+    public static IEnumerable<IEnumerable<T>> Combinations<T>(this IList<T> elements, int k) {
+      if (k > elements.Count)
+        throw new ArgumentException();
+
+      if (k == 1) {
+        foreach (var element in elements)
+          yield return new[] { element };
+        yield break;
+      }
+
+      int n = elements.Count;
+      var range = Enumerable.Range(0, k).ToArray();
+      var length = BinomialCoefficient(n, k);
+
+      for (int i = 0; i < length; ++i) {
+        yield return range.Select(x => elements[x]).ToArray();
+
+        if (i == length - 1) break;
+        var m = k - 1;
+        var max = n - 1;
+
+        while (range[m] == max) { --m; --max; }
+        range[m]++;
+        for (int j = m + 1; j < k; ++j) {
+          range[j] = range[j - 1] + 1;
+        }
+      }
+    }
+
+    /// <summary>
+    /// This function gets the total number of unique combinations based upon N and K,
+    /// where N is the total number of items and K is the size of the group.
+    /// It calculates the total number of unique combinations C(N, K) = N! / ( K! (N - K)! )
+    /// using the  recursion C(N+1, K+1) = (N+1 / K+1) * C(N, K).
+    /// <remarks>http://blog.plover.com/math/choose.html</remarks>
+    /// <remark>https://en.wikipedia.org/wiki/Binomial_coefficient#Multiplicative_formula</remark>
+    /// <param name="n">The number of elements</param>
+    /// <param name="k">The size of the group</param>
+    /// <returns>The binomial coefficient C(N, K)</returns>
+    /// </summary>
+    public static long BinomialCoefficient(long n, long k) {
+      if (k > n) return 0;
+      if (k == n) return 1;
+      if (k > n - k)
+        k = n - k;
+
+      // enable explicit overflow checking for very large coefficients
+      checked {
+        long r = 1;
+        for (long d = 1; d <= k; d++) {
+          r *= n--;
+          r /= d;
+        }
+        return r;
+      }
+    }
   }
 }
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EnumerableStatisticExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EnumerableStatisticExtensions.cs	(revision 15651)
+++ 	(revision )
@@ -1,212 +1,0 @@
-#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.Diagnostics.Contracts;
-using System.Linq;
-
-namespace HeuristicLab.Common {
-  public static class EnumerableStatisticExtensions {
-    /// <summary>
-    /// Calculates the median element of the enumeration.
-    /// </summary>
-    /// <param name="values"></param>
-    /// <returns></returns>
-    public static double Median(this IEnumerable<double> values) {
-      // See unit tests for comparison with naive implementation
-      return Quantile(values, 0.5);
-    }
-
-    /// <summary>
-    /// Calculates the alpha-quantile element of the enumeration.
-    /// </summary>
-    /// <param name="values"></param>
-    /// <returns></returns>
-    public static double Quantile(this IEnumerable<double> values, double alpha) {
-      // See unit tests for comparison with naive implementation
-      double[] valuesArr = values.ToArray();
-      int n = valuesArr.Length;
-      if (n == 0) throw new InvalidOperationException("Enumeration contains no elements.");
-
-      // "When N is even, statistics books define the median as the arithmetic mean of the elements k = N/2 
-      // and k = N/2 + 1 (that is, N/2 from the bottom and N/2 from the top). 
-      // If you accept such pedantry, you must perform two separate selections to find these elements."
-
-      // return the element at Math.Ceiling (if n*alpha is fractional) or the average of two elements if n*alpha is integer.
-      var pos = n * alpha;
-      Contract.Assert(pos >= 0);
-      Contract.Assert(pos < n);
-      bool isInteger = Math.Round(pos).IsAlmost(pos);
-      if (isInteger) {
-        return 0.5 * (Select((int)pos - 1, valuesArr) + Select((int)pos, valuesArr));
-      } else {
-        return Select((int)Math.Ceiling(pos) - 1, valuesArr);
-      }
-    }
-
-    // Numerical Recipes in C++, §8.5 Selecting the Mth Largest, O(n)
-    // Given k in [0..n-1] returns an array value from array arr[0..n-1] such that k array values are 
-    // less than or equal to the one returned. The input array will be rearranged to have this value in 
-    // location arr[k], with all smaller elements moved to arr[0..k-1] (in arbitrary order) and all 
-    // larger elements in arr[k+1..n-1] (also in arbitrary order).
-    // 
-    // Could be changed to Select<T> where T is IComparable but in this case is significantly slower for double values
-    private static double Select(int k, double[] arr) {
-      Contract.Assert(arr.GetLowerBound(0) == 0);
-      Contract.Assert(k >= 0 && k < arr.Length);
-      int i, ir, j, l, mid, n = arr.Length;
-      double a;
-      l = 0;
-      ir = n - 1;
-      for (; ; ) {
-        if (ir <= l + 1) {
-          // Active partition contains 1 or 2 elements.
-          if (ir == l + 1 && arr[ir] < arr[l]) {
-            // if (ir == l + 1 && arr[ir].CompareTo(arr[l]) < 0) {
-            // Case of 2 elements.
-            // SWAP(arr[l], arr[ir]);
-            double temp = arr[l];
-            arr[l] = arr[ir];
-            arr[ir] = temp;
-          }
-          return arr[k];
-        } else {
-          mid = (l + ir) >> 1; // Choose median of left, center, and right elements
-          {
-            // SWAP(arr[mid], arr[l + 1]); // as partitioning element a. Also
-            double temp = arr[mid];
-            arr[mid] = arr[l + 1];
-            arr[l + 1] = temp;
-          }
-
-          if (arr[l] > arr[ir]) {
-            // if (arr[l].CompareTo(arr[ir]) > 0) {  // rearrange so that arr[l] arr[ir] <= arr[l+1],
-            // SWAP(arr[l], arr[ir]); . arr[ir] >= arr[l+1]
-            double temp = arr[l];
-            arr[l] = arr[ir];
-            arr[ir] = temp;
-          }
-
-          if (arr[l + 1] > arr[ir]) {
-            // if (arr[l + 1].CompareTo(arr[ir]) > 0) {
-            // SWAP(arr[l + 1], arr[ir]);
-            double temp = arr[l + 1];
-            arr[l + 1] = arr[ir];
-            arr[ir] = temp;
-          }
-          if (arr[l] > arr[l + 1]) {
-            //if (arr[l].CompareTo(arr[l + 1]) > 0) {
-            // SWAP(arr[l], arr[l + 1]);
-            double temp = arr[l];
-            arr[l] = arr[l + 1];
-            arr[l + 1] = temp;
-
-          }
-          i = l + 1; // Initialize pointers for partitioning.
-          j = ir;
-          a = arr[l + 1]; // Partitioning element.
-          for (; ; ) { // Beginning of innermost loop.
-            do i++; while (arr[i] < a /* arr[i].CompareTo(a) < 0 */); // Scan up to find element > a.
-            do j--; while (arr[j] > a /* arr[j].CompareTo(a) > 0 */); // Scan down to find element < a.
-            if (j < i) break; // Pointers crossed. Partitioning complete.
-            {
-              // SWAP(arr[i], arr[j]);
-              double temp = arr[i];
-              arr[i] = arr[j];
-              arr[j] = temp;
-            }
-          } // End of innermost loop.
-          arr[l + 1] = arr[j]; // Insert partitioning element.
-          arr[j] = a;
-          if (j >= k) ir = j - 1; // Keep active the partition that contains the
-          if (j <= k) l = i; // kth element.
-        }
-      }
-    }
-
-    /// <summary>
-    /// Calculates the range (max - min) of the enumeration.
-    /// </summary>
-    /// <param name="values"></param>
-    /// <returns></returns>
-    public static double Range(this IEnumerable<double> values) {
-      double min = double.PositiveInfinity;
-      double max = double.NegativeInfinity;
-      int i = 0;
-      foreach (var e in values) {
-        if (min > e) min = e;
-        if (max < e) max = e;
-        i++;
-      }
-      if (i < 1) throw new ArgumentException("The enumerable must contain at least two elements", "values");
-      return max - min;
-    }
-
-
-    /// <summary>
-    /// Calculates the standard deviation of values.
-    /// </summary>
-    /// <param name="values"></param>
-    /// <returns></returns>
-    public static double StandardDeviation(this IEnumerable<double> values) {
-      return Math.Sqrt(Variance(values));
-    }
-
-    /// <summary>
-    /// Calculates the variance of values. (sum (x - x_mean)² / n)
-    /// </summary>
-    /// <param name="values"></param>
-    /// <returns></returns>
-    public static double Variance(this IEnumerable<double> values) {
-      int m_n = 0;
-      double m_oldM = 0.0;
-      double m_newM = 0.0;
-      double m_oldS = 0.0;
-      double m_newS = 0.0;
-      foreach (double x in values) {
-        m_n++;
-        if (m_n == 1) {
-          m_oldM = m_newM = x;
-          m_oldS = 0.0;
-        } else {
-          m_newM = m_oldM + (x - m_oldM) / m_n;
-          m_newS = m_oldS + (x - m_oldM) * (x - m_newM);
-
-          // set up for next iteration
-          m_oldM = m_newM;
-          m_oldS = m_newS;
-        }
-      }
-      return ((m_n > 1) ? m_newS / (m_n - 1) : 0.0);
-    }
-
-    public static IEnumerable<double> LimitToRange(this IEnumerable<double> values, double min, double max) {
-      if (min > max) throw new ArgumentException(string.Format("Minimum {0} is larger than maximum {1}.", min, max));
-      foreach (var x in values) {
-        if (double.IsNaN(x)) yield return (max + min) / 2.0;
-        else if (x < min) yield return min;
-        else if (x > max) yield return max;
-        else yield return x;
-      }
-    }
-  }
-}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EventArgs.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EventArgs.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/EventArgs.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ExceptionExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ExceptionExtensions.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ExceptionExtensions.cs	(revision 15973)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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;
+
+namespace HeuristicLab.Common {
+  public static class ExceptionExtensions {
+    public static void FlattenAndHandle(this AggregateException exception, IEnumerable<Type> exceptionsToHandle, Action<Exception> unhandledCallback) {
+      try {
+        var toHandle = new HashSet<Type>(exceptionsToHandle);
+        exception.Flatten().Handle(x => toHandle.Contains(x.GetType()));
+      } catch (AggregateException remaining) {
+        if (remaining.InnerExceptions.Count == 1) unhandledCallback(remaining.InnerExceptions[0]);
+        else unhandledCallback(remaining);
+      }
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/HeuristicLab.Common-3.3.csproj
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/HeuristicLab.Common-3.3.csproj	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/HeuristicLab.Common-3.3.csproj	(revision 15973)
@@ -123,4 +123,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="AsyncHelper.cs" />
     <Compile Include="CancelEventArgs.cs" />
     <None Include="Plugin.cs.frame" />
@@ -132,4 +133,6 @@
     <Compile Include="ArrayExtensions.cs" />
     <Compile Include="ErrorHandling.cs" />
+    <Compile Include="ExceptionExtensions.cs" />
+    <Compile Include="Statistics\EmpiricalCumulativeDistributionFunction.cs" />
     <Compile Include="ListExtensions.cs" />
     <Compile Include="Point2D.cs" />
@@ -140,5 +143,5 @@
     <Compile Include="DeepCloneable.cs" />
     <Compile Include="Content\IContent.cs" />
-    <Compile Include="EnumerableStatisticExtensions.cs" />
+    <Compile Include="Statistics\EnumerableStatisticExtensions.cs" />
     <Compile Include="IDeepCloneable.cs" />
     <Compile Include="Plugin.cs" />
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/IDeepCloneable.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/IDeepCloneable.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/IDeepCloneable.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ListExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ListExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ListExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/MatrixExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/MatrixExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/MatrixExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -20,4 +20,6 @@
 #endregion
 
+using System.Diagnostics.Contracts;
+
 namespace HeuristicLab.Common {
   public static class MatrixExtensions {
@@ -35,4 +37,63 @@
       return result;
     }
+
+    /// <summary>
+    /// Concatenates matrices vertically.
+    /// A      B
+    /// 1 2    9 8
+    /// 3 4    7 6
+    /// 
+    /// VertCat(A, B)
+    /// 1 2 
+    /// 3 4
+    /// 9 8
+    /// 7 6
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    /// <param name="a"></param>
+    /// <param name="b"></param>
+    /// <returns>A new matrix with the number of rows = a.GetLength(0) + b.GetLength(0)</returns>
+    public static T[,] VertCat<T>(this T[,] a, T[,] b) {
+      Contract.Assert(a.GetLength(1) == b.GetLength(1));
+      var aLen = a.GetLength(0);
+      var bLen = b.GetLength(0);
+      var result = new T[aLen + bLen, a.GetLength(1)];
+      for (int i = 0; i < aLen; i++)
+        for (int j = 0; j < a.GetLength(1); j++)
+          result[i, j] = a[i, j];
+      for (int i = 0; i < bLen; i++)
+        for (int j = 0; j < b.GetLength(1); j++)
+          result[i + aLen, j] = b[i, j];
+
+      return result;
+    }
+
+    /// <summary>
+    /// Concatenates matrices horizontally.
+    /// A      B
+    /// 1 2    9 8
+    /// 3 4    7 6
+    /// 
+    /// HorzCat(A, B)
+    /// 1 2 9 8
+    /// 3 4 7 6
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    /// <param name="a"></param>
+    /// <param name="b"></param>
+    /// <returns>A new matrix with the number of columns = a.GetLength(1) + b.GetLength(1)</returns>
+    public static T[,] HorzCat<T>(this T[,] a, T[,] b) {
+      Contract.Assert(a.GetLength(0) == b.GetLength(0));
+      var aLen = a.GetLength(1);
+      var bLen = b.GetLength(1);
+      var result = new T[a.GetLength(0), aLen + bLen];
+      for (int i = 0; i < a.GetLength(0); i++)
+        for (int j = 0; j < aLen; j++)
+          result[i, j] = a[i, j];
+      for (int i = 0; i < a.GetLength(0); i++)
+        for (int j = 0; j < bLen; j++)
+          result[i, j + aLen] = b[i, j];
+      return result;
+    }
   }
 }
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/NaturalStringComparer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/NaturalStringComparer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/NaturalStringComparer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ObjectExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ObjectExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ObjectExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -30,4 +30,10 @@
 
 namespace HeuristicLab.Common {
+
+  [AttributeUsage(AttributeTargets.Field)]
+  // this attribute can be used to mark fields that should be excluded from object graph traversal
+  public class ExcludeFromObjectGraphTraversalAttribute : Attribute {
+  }
+
   public static class ObjectExtensions {
     public static IEnumerable<T> ToEnumerable<T>(this T obj) {
@@ -66,4 +72,5 @@
     ///   * string, decimal, DateTime
     ///   * Arrays of types not collected
+    ///   * All types from System.Reflection.Emit
     /// </summary>
     private static bool ExcludeType(Type type) {
@@ -77,5 +84,5 @@
              typeof(Delegate).IsAssignableFrom(type) ||
              typeof(Pointer).IsAssignableFrom(type) ||
-             type == typeof(System.Reflection.Emit.SignatureHelper) ||
+             type.Namespace == "System.Reflection.Emit" ||
              (type.HasElementType && ExcludeType(type.GetElementType()));
     }
@@ -112,13 +119,17 @@
         }
       } else {
-        if (!fieldInfos.ContainsKey(type))
-          fieldInfos[type] = type.GetAllFields().ToArray();
-        foreach (FieldInfo f in fieldInfos[type]) {
+        FieldInfo[] fieldInfo;
+        if (!fieldInfos.TryGetValue(type, out fieldInfo)) {
+          fieldInfo = type.GetAllFields()
+            .Where(fi => !Attribute.IsDefined(fi, typeof(ExcludeFromObjectGraphTraversalAttribute)))
+            .ToArray();
+          fieldInfos.Add(type, fieldInfo);
+        }
+        foreach (FieldInfo f in fieldInfo) {
           if (excludeStaticMembers && f.IsStatic) continue;
           object fieldValue;
           try {
             fieldValue = f.GetValue(obj);
-          }
-          catch (SecurityException) {
+          } catch (SecurityException) {
             continue;
           }
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Plugin.cs.frame
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Plugin.cs.frame	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Plugin.cs.frame	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -29,5 +29,5 @@
   /// Plugin class for HeuristicLab.Common plugin.
   /// </summary>
-  [Plugin("HeuristicLab.Common", "3.3.13.$WCREV$")]
+  [Plugin("HeuristicLab.Common", "3.3.15.$WCREV$")]
   [PluginFile("HeuristicLab.Common-3.3.dll", PluginFileType.Assembly)]
   public class HeuristicLabCommonPlugin : PluginBase {
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Point2D.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Point2D.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Point2D.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,5 +26,5 @@
 namespace HeuristicLab.Common {
   [Serializable]
-  public struct Point2D<T> where T : struct {
+  public struct Point2D<T> where T : struct, IEquatable<T> {
     public static readonly Point2D<T> Empty = new Point2D<T>();
 
@@ -38,4 +38,9 @@
     }
 
+    private object tag;
+    public object Tag {
+      get { return tag; }
+    }
+
     [Browsable(false)]
     public bool IsEmpty {
@@ -43,11 +48,16 @@
     }
 
-    public Point2D(T x, T y) {
+    public Point2D(T x, T y, object tag = null) {
       this.x = x;
       this.y = y;
+      this.tag = tag;
+    }
+
+    public static Point2D<T> Create(T x, T y, object tag = null) {
+      return new Point2D<T>(x, y, tag);
     }
 
     public static bool operator ==(Point2D<T> left, Point2D<T> right) {
-      return left.x.Equals(right.x) && left.y.Equals(right.y);
+      return left.x.Equals(right.x) && left.y.Equals(right.y) && left.tag == right.tag;
     }
     public static bool operator !=(Point2D<T> left, Point2D<T> right) {
@@ -59,5 +69,6 @@
         return false;
       Point2D<T> point = (Point2D<T>)obj;
-      return x.Equals(point.x) && y.Equals(point.y) && GetType().Equals(point.GetType());
+      return GetType() == point.GetType() && x.Equals(point.x) && y.Equals(point.y) &&
+             ((tag != null && tag.Equals(point.tag)) || tag == point.tag);
     }
     public override int GetHashCode() {
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Properties/AssemblyInfo.cs.frame	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Properties/AssemblyInfo.cs.frame	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 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-2015 HEAL")]
+[assembly: AssemblyCopyright("(c) 2002-2018 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.13.$WCREV$")]
+[assembly: AssemblyFileVersion("3.3.15.$WCREV$")]
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ReferenceEqualityComparer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ReferenceEqualityComparer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/ReferenceEqualityComparer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/SequenceGenerator.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/SequenceGenerator.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/SequenceGenerator.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EmpiricalCumulativeDistributionFunction.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EmpiricalCumulativeDistributionFunction.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EmpiricalCumulativeDistributionFunction.cs	(revision 15973)
@@ -0,0 +1,130 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.Common {
+  public class EmpiricalCumulativeDistributionFunction {
+    private static readonly AbscissaComparer abscissaComparer = new AbscissaComparer();
+    private static readonly OrdinateComparer ordinateComparer = new OrdinateComparer();
+
+    private List<Point2D<double>> ecdf;
+    public IEnumerable<Point2D<double>> SupportingPoints {
+      get { return ecdf; }
+    }
+    
+    public EmpiricalCumulativeDistributionFunction(IList<double> sample) {
+      ecdf = new List<Point2D<double>>();
+
+      var len = sample.Count;
+      var cumulative = 0;
+      var localcumulative = 0;
+      var prev = double.NaN;
+      foreach (var p in sample.OrderBy(x => x)) {
+        if (double.IsNaN(p) || double.IsInfinity(p)) continue;
+        if (!double.IsNaN(prev) && prev < p) {
+          cumulative += localcumulative;
+          localcumulative = 0;
+          ecdf.Add(Point2D<double>.Create(prev, cumulative / (double)len));
+        }
+        prev = p;
+        localcumulative++;
+      }
+      if (!double.IsNaN(prev)) {
+        cumulative += localcumulative;
+        ecdf.Add(Point2D<double>.Create(prev, cumulative / (double)len));
+      }
+    }
+    public EmpiricalCumulativeDistributionFunction(IEnumerable<Point2D<double>> ecdf) {
+      this.ecdf = new List<Point2D<double>>();
+      var prev = Point2D<double>.Empty;
+      foreach (var point in ecdf) {
+        if (point.Y < 0 || point.Y > 1 || double.IsNaN(point.X) || double.IsInfinity(point.X)
+          || point.IsEmpty || (!prev.IsEmpty && (point.X <= prev.X || point.Y <= prev.Y)))
+          throw new ArgumentException("Invalid supporting points of a cumulative distribution function. Must be strictly monotonically increasing in both X and Y with X in R and Y in [0;1].", "ecdf");
+
+        this.ecdf.Add(point);
+        prev = point;
+      }
+    }
+
+    public double Evaluate(double x) {
+      if (ecdf.Count == 0) return double.NaN;
+      if (x < ecdf[0].X) return 0;
+      var last = ecdf[ecdf.Count - 1];
+      if (x >= last.X) return last.Y;
+
+      var index = ecdf.BinarySearch(Point2D<double>.Create(x, 0), abscissaComparer);
+      if (index >= 0) return ecdf[index].Y;
+      return ecdf[~index - 1].Y;
+    }
+
+    public double InterpolateLinear(double x) {
+      if (ecdf.Count == 0) return double.NaN;
+      if (x < ecdf[0].X) return 0;
+      var last = ecdf[ecdf.Count - 1];
+      if (x >= last.X) return last.Y;
+
+      var index = ecdf.BinarySearch(Point2D<double>.Create(x, 0), abscissaComparer);
+      if (index >= 0) return ecdf[index].Y;
+      var prev = ecdf[~index - 1];
+      var next = ecdf[~index];
+      return prev.Y + (next.Y - prev.Y) * ((x - prev.X) / (next.X - prev.X));
+    }
+
+    public double InterpolateNearest(double x) {
+      if (ecdf.Count == 0) return double.NaN;
+      if (x < ecdf[0].X) return 0;
+      var last = ecdf[ecdf.Count - 1];
+      if (x >= last.X) return last.Y;
+
+      var index = ecdf.BinarySearch(Point2D<double>.Create(x, 0), abscissaComparer);
+      if (index >= 0) return ecdf[index].Y;
+      var prev = ecdf[~index - 1];
+      var next = ecdf[~index];
+      if (x - prev.X < next.X - x) return prev.Y;
+      return next.Y;
+    }
+
+    public double Inverse(double y) {
+      if (ecdf.Count == 0) return double.NaN;
+      if (y < 0 || y > 1) throw new ArgumentException("parameter must be in interval [0;1]", "y");
+      if (ecdf[ecdf.Count - 1].Y < y) return double.PositiveInfinity;
+      var index = ecdf.BinarySearch(Point2D<double>.Create(0, y), ordinateComparer);
+      if (index >= 0) return ecdf[index].X;
+      return ecdf[Math.Max(~index - 1, 0)].X;
+    }
+
+    private class AbscissaComparer : Comparer<Point2D<double>> {
+      public override int Compare(Point2D<double> x, Point2D<double> y) {
+        return x.X.CompareTo(y.X);
+      }
+    }
+
+    private class OrdinateComparer : Comparer<Point2D<double>> {
+      public override int Compare(Point2D<double> x, Point2D<double> y) {
+        return x.Y.CompareTo(y.Y);
+      }
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EnumerableStatisticExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EnumerableStatisticExtensions.cs	(revision 15973)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/Statistics/EnumerableStatisticExtensions.cs	(revision 15973)
@@ -0,0 +1,239 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+
+namespace HeuristicLab.Common {
+  public static class EnumerableStatisticExtensions {
+    /// <summary>
+    /// Calculates the median element of the enumeration.
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double Median(this IEnumerable<double> values) {
+      // See unit tests for comparison with naive implementation
+      return Quantile(values, 0.5);
+    }
+
+    /// <summary>
+    /// Calculates the alpha-quantile element of the enumeration.
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double Quantile(this IEnumerable<double> values, double alpha) {
+      // See unit tests for comparison with naive implementation
+      double[] valuesArr = values.ToArray();
+      int n = valuesArr.Length;
+      if (n == 0) throw new InvalidOperationException("Enumeration contains no elements.");
+
+      // "When N is even, statistics books define the median as the arithmetic mean of the elements k = N/2 
+      // and k = N/2 + 1 (that is, N/2 from the bottom and N/2 from the top). 
+      // If you accept such pedantry, you must perform two separate selections to find these elements."
+
+      // return the element at Math.Ceiling (if n*alpha is fractional) or the average of two elements if n*alpha is integer.
+      var pos = n * alpha;
+      Contract.Assert(pos >= 0);
+      Contract.Assert(pos < n);
+      bool isInteger = Math.Round(pos).IsAlmost(pos);
+      if (isInteger) {
+        return 0.5 * (Select((int)pos - 1, valuesArr) + Select((int)pos, valuesArr));
+      } else {
+        return Select((int)Math.Ceiling(pos) - 1, valuesArr);
+      }
+    }
+
+    // Numerical Recipes in C++, §8.5 Selecting the Mth Largest, O(n)
+    // Given k in [0..n-1] returns an array value from array arr[0..n-1] such that k array values are 
+    // less than or equal to the one returned. The input array will be rearranged to have this value in 
+    // location arr[k], with all smaller elements moved to arr[0..k-1] (in arbitrary order) and all 
+    // larger elements in arr[k+1..n-1] (also in arbitrary order).
+    // 
+    // Could be changed to Select<T> where T is IComparable but in this case is significantly slower for double values
+    private static double Select(int k, double[] arr) {
+      Contract.Assert(arr.GetLowerBound(0) == 0);
+      Contract.Assert(k >= 0 && k < arr.Length);
+      int i, ir, j, l, mid, n = arr.Length;
+      double a;
+      l = 0;
+      ir = n - 1;
+      for (; ; ) {
+        if (ir <= l + 1) {
+          // Active partition contains 1 or 2 elements.
+          if (ir == l + 1 && arr[ir] < arr[l]) {
+            // if (ir == l + 1 && arr[ir].CompareTo(arr[l]) < 0) {
+            // Case of 2 elements.
+            // SWAP(arr[l], arr[ir]);
+            double temp = arr[l];
+            arr[l] = arr[ir];
+            arr[ir] = temp;
+          }
+          return arr[k];
+        } else {
+          mid = (l + ir) >> 1; // Choose median of left, center, and right elements
+          {
+            // SWAP(arr[mid], arr[l + 1]); // as partitioning element a. Also
+            double temp = arr[mid];
+            arr[mid] = arr[l + 1];
+            arr[l + 1] = temp;
+          }
+
+          if (arr[l] > arr[ir]) {
+            // if (arr[l].CompareTo(arr[ir]) > 0) {  // rearrange so that arr[l] arr[ir] <= arr[l+1],
+            // SWAP(arr[l], arr[ir]); . arr[ir] >= arr[l+1]
+            double temp = arr[l];
+            arr[l] = arr[ir];
+            arr[ir] = temp;
+          }
+
+          if (arr[l + 1] > arr[ir]) {
+            // if (arr[l + 1].CompareTo(arr[ir]) > 0) {
+            // SWAP(arr[l + 1], arr[ir]);
+            double temp = arr[l + 1];
+            arr[l + 1] = arr[ir];
+            arr[ir] = temp;
+          }
+          if (arr[l] > arr[l + 1]) {
+            //if (arr[l].CompareTo(arr[l + 1]) > 0) {
+            // SWAP(arr[l], arr[l + 1]);
+            double temp = arr[l];
+            arr[l] = arr[l + 1];
+            arr[l + 1] = temp;
+
+          }
+          i = l + 1; // Initialize pointers for partitioning.
+          j = ir;
+          a = arr[l + 1]; // Partitioning element.
+          for (; ; ) { // Beginning of innermost loop.
+            do i++; while (arr[i] < a /* arr[i].CompareTo(a) < 0 */); // Scan up to find element > a.
+            do j--; while (arr[j] > a /* arr[j].CompareTo(a) > 0 */); // Scan down to find element < a.
+            if (j < i) break; // Pointers crossed. Partitioning complete.
+            {
+              // SWAP(arr[i], arr[j]);
+              double temp = arr[i];
+              arr[i] = arr[j];
+              arr[j] = temp;
+            }
+          } // End of innermost loop.
+          arr[l + 1] = arr[j]; // Insert partitioning element.
+          arr[j] = a;
+          if (j >= k) ir = j - 1; // Keep active the partition that contains the
+          if (j <= k) l = i; // kth element.
+        }
+      }
+    }
+
+    /// <summary>
+    /// Calculates the range (max - min) of the enumeration.
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double Range(this IEnumerable<double> values) {
+      double min = double.PositiveInfinity;
+      double max = double.NegativeInfinity;
+      int i = 0;
+      foreach (var e in values) {
+        if (min > e) min = e;
+        if (max < e) max = e;
+        i++;
+      }
+      if (i < 1) throw new ArgumentException("The enumerable must contain at least two elements", "values");
+      return max - min;
+    }
+
+
+    /// <summary>
+    /// Calculates the sample standard deviation of values.
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double StandardDeviation(this IEnumerable<double> values) {
+      return Math.Sqrt(Variance(values));
+    }
+
+    /// <summary>
+    /// Calculates the population standard deviation of values.
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double StandardDeviationPop(this IEnumerable<double> values) {
+      return Math.Sqrt(VariancePop(values));
+    }
+
+    /// <summary>
+    /// Calculates the sample variance of values. (sum (x - x_mean)² / (n-1))
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double Variance(this IEnumerable<double> values) {
+      return Variance(values, true);
+    }
+
+    /// <summary>
+    /// Calculates the population variance of values. (sum (x - x_mean)² / n)
+    /// </summary>
+    /// <param name="values"></param>
+    /// <returns></returns>
+    public static double VariancePop(this IEnumerable<double> values) {
+      return Variance(values, false);
+    }
+
+    private static double Variance(IEnumerable<double> values, bool sampleVariance) {
+      int m_n = 0;
+      double m_oldM = 0.0;
+      double m_newM = 0.0;
+      double m_oldS = 0.0;
+      double m_newS = 0.0;
+      foreach (double x in values) {
+        m_n++;
+        if (m_n == 1) {
+          m_oldM = m_newM = x;
+          m_oldS = 0.0;
+        } else {
+          m_newM = m_oldM + (x - m_oldM) / m_n;
+          m_newS = m_oldS + (x - m_oldM) * (x - m_newM);
+
+          // set up for next iteration
+          m_oldM = m_newM;
+          m_oldS = m_newS;
+        }
+      }
+
+      if (m_n == 0) return double.NaN;
+      if (m_n == 1) return 0.0;
+
+      if (sampleVariance) return m_newS / (m_n - 1);
+      else return m_newS / m_n;
+    }
+
+    public static IEnumerable<double> LimitToRange(this IEnumerable<double> values, double min, double max) {
+      if (min > max) throw new ArgumentException(string.Format("Minimum {0} is larger than maximum {1}.", min, max));
+      foreach (var x in values) {
+        if (double.IsNaN(x)) yield return (max + min) / 2.0;
+        else if (x < min) yield return min;
+        else if (x > max) yield return max;
+        else yield return x;
+      }
+    }
+  }
+}
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TimeSpanHelper.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TimeSpanHelper.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TimeSpanHelper.cs	(revision 15973)
@@ -2,5 +2,5 @@
 
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeEqualityComparer.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeEqualityComparer.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeEqualityComparer.cs	(revision 15973)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeExtensions.cs
===================================================================
--- branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeExtensions.cs	(revision 15651)
+++ branches/2522_RefactorPluginInfrastructure/HeuristicLab.Common/3.3/TypeExtensions.cs	(revision 15973)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
