Index: branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/AlgorithmView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/BasicAlgorithmView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -36,10 +36,10 @@
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
-      pauseButton.Enabled = false;
+      pauseButton.Enabled &= Content != null && Content.SupportsPause;
     }
 
     protected override void SetEnabledStateOfExecutableButtons() {
       base.SetEnabledStateOfExecutableButtons();
-      pauseButton.Enabled = false;
+      pauseButton.Enabled &= Content != null && Content.SupportsPause;
     }
   }
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/BatchRunView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/CreateNewSingleEncodingDialog.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/EngineAlgorithmView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentListView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentTreeView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ExperimentView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 15281)
@@ -166,4 +166,10 @@
       <DependentUpon>ExperimentListView.cs</DependentUpon>
     </Compile>
+    <Compile Include="ResultParameterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ResultParameterView.Designer.cs">
+      <DependentUpon>ResultParameterView.cs</DependentUpon>
+    </Compile>
     <Compile Include="MultiEncodingView.cs">
       <SubType>UserControl</SubType>
@@ -262,4 +268,16 @@
     <Compile Include="RunCollectionConstraintViews\RunCollectionEqualityConstraintView.Designer.cs">
       <DependentUpon>RunCollectionEqualityConstraintView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionParameterAnalysisView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionParameterAnalysisView.Designer.cs">
+      <DependentUpon>RunCollectionParameterAnalysisView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionRLDView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RunCollectionViews\RunCollectionRLDView.Designer.cs">
+      <DependentUpon>RunCollectionRLDView.cs</DependentUpon>
     </Compile>
     <Compile Include="RunCollectionViews\RunCollectionTableView.cs">
@@ -405,4 +423,14 @@
       <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project>
       <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters.Views\3.3\HeuristicLab.Parameters.Views-3.3.csproj">
+      <Project>{ae5b1ce5-9862-4d6f-a700-d72cd9aea295}</Project>
+      <Name>HeuristicLab.Parameters.Views-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56f9106a-079f-4c61-92f6-86a84c2d84b7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
       <Private>False</Private>
     </ProjectReference>
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/IOptimizerView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ISolutionSimilarityCalculatorView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/MultiEncodingView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/OptimizerListView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/Plugin.cs.frame	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -26,5 +26,5 @@
   /// Plugin class for HeuristicLab.Optimization.Views plugin.
   /// </summary>
-  [Plugin("HeuristicLab.Optimization.Views", "3.3.13.$WCREV$")]
+  [Plugin("HeuristicLab.Optimization.Views", "3.3.14.$WCREV$")]
   [PluginFile("HeuristicLab.Optimization.Views-3.3.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.Analysis", "3.3")]
@@ -39,4 +39,5 @@
   [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
   [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters.Views", "3.3")]
   [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
   [PluginDependency("HeuristicLab.Problems.Instances.Views", "3.3")]
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemInstanceProviderView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ProblemView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/Properties/AssemblyInfo.cs.frame	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 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-2016 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.14.$WCREV$")]
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultCollectionView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.Designer.cs	(revision 15281)
@@ -0,0 +1,171 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class ResultParameterView<T> {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+    
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.resultCollectionNameTextBox = new System.Windows.Forms.TextBox();
+      this.resultCollectionNameLabel = new System.Windows.Forms.Label();
+      this.defaultValueGroupBox = new System.Windows.Forms.GroupBox();
+      this.removeDefaultValueButton = new System.Windows.Forms.Button();
+      this.setDefaultValueButton = new System.Windows.Forms.Button();
+      this.defaultValueViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.defaultValueGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // actualNameTextBox
+      // 
+      this.actualNameTextBox.Location = new System.Drawing.Point(98, 26);
+      this.actualNameTextBox.Size = new System.Drawing.Size(288, 20);
+      // 
+      // dataTypeTextBox
+      // 
+      this.dataTypeTextBox.Location = new System.Drawing.Point(98, 52);
+      this.dataTypeTextBox.Size = new System.Drawing.Size(288, 20);
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      this.nameTextBox.Location = new System.Drawing.Point(98, 0);
+      this.nameTextBox.Size = new System.Drawing.Size(263, 20);
+      // 
+      // resultCollectionNameTextBox
+      // 
+      this.resultCollectionNameTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.resultCollectionNameTextBox.Location = new System.Drawing.Point(98, 78);
+      this.resultCollectionNameTextBox.Name = "resultCollectionNameTextBox";
+      this.resultCollectionNameTextBox.Size = new System.Drawing.Size(288, 20);
+      this.resultCollectionNameTextBox.TabIndex = 6;
+      this.resultCollectionNameTextBox.Validated += new System.EventHandler(this.resultNameTextBox_Validated);
+      // 
+      // resultCollectionNameLabel
+      // 
+      this.resultCollectionNameLabel.AutoSize = true;
+      this.resultCollectionNameLabel.Location = new System.Drawing.Point(3, 81);
+      this.resultCollectionNameLabel.Name = "resultCollectionNameLabel";
+      this.resultCollectionNameLabel.Size = new System.Drawing.Size(89, 13);
+      this.resultCollectionNameLabel.TabIndex = 5;
+      this.resultCollectionNameLabel.Text = "&Result Collection:";
+      // 
+      // defaultValueGroupBox
+      // 
+      this.defaultValueGroupBox.AllowDrop = true;
+      this.defaultValueGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.defaultValueGroupBox.Controls.Add(this.removeDefaultValueButton);
+      this.defaultValueGroupBox.Controls.Add(this.setDefaultValueButton);
+      this.defaultValueGroupBox.Controls.Add(this.defaultValueViewHost);
+      this.defaultValueGroupBox.Location = new System.Drawing.Point(0, 104);
+      this.defaultValueGroupBox.Name = "defaultValueGroupBox";
+      this.defaultValueGroupBox.Size = new System.Drawing.Size(386, 222);
+      this.defaultValueGroupBox.TabIndex = 7;
+      this.defaultValueGroupBox.TabStop = false;
+      this.defaultValueGroupBox.Text = "Default Value";
+      this.defaultValueGroupBox.DragDrop += new System.Windows.Forms.DragEventHandler(this.defaultValueGroupBox_DragDrop);
+      this.defaultValueGroupBox.DragEnter += new System.Windows.Forms.DragEventHandler(this.defaultValueGroupBox_DragEnterOver);
+      this.defaultValueGroupBox.DragOver += new System.Windows.Forms.DragEventHandler(this.defaultValueGroupBox_DragEnterOver);
+      // 
+      // removeDefaultValueButton
+      // 
+      this.removeDefaultValueButton.Location = new System.Drawing.Point(38, 19);
+      this.removeDefaultValueButton.Name = "removeDefaultValueButton";
+      this.removeDefaultValueButton.Size = new System.Drawing.Size(26, 23);
+      this.removeDefaultValueButton.TabIndex = 1;
+      this.removeDefaultValueButton.Text = "Remove";
+      this.removeDefaultValueButton.UseVisualStyleBackColor = true;
+      this.removeDefaultValueButton.Click += new System.EventHandler(this.removeDefaultValueButton_Click);
+      // 
+      // setDefaultValueButton
+      // 
+      this.setDefaultValueButton.Location = new System.Drawing.Point(6, 19);
+      this.setDefaultValueButton.Name = "setDefaultValueButton";
+      this.setDefaultValueButton.Size = new System.Drawing.Size(26, 23);
+      this.setDefaultValueButton.TabIndex = 1;
+      this.setDefaultValueButton.Text = "Set";
+      this.setDefaultValueButton.UseVisualStyleBackColor = true;
+      this.setDefaultValueButton.Click += new System.EventHandler(this.setDefaultValueButton_Click);
+      // 
+      // defaultValueViewHost
+      // 
+      this.defaultValueViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.defaultValueViewHost.Caption = "View";
+      this.defaultValueViewHost.Content = null;
+      this.defaultValueViewHost.Enabled = false;
+      this.defaultValueViewHost.Location = new System.Drawing.Point(6, 48);
+      this.defaultValueViewHost.Name = "defaultValueViewHost";
+      this.defaultValueViewHost.ReadOnly = false;
+      this.defaultValueViewHost.Size = new System.Drawing.Size(374, 168);
+      this.defaultValueViewHost.TabIndex = 0;
+      this.defaultValueViewHost.ViewsLabelVisible = true;
+      this.defaultValueViewHost.ViewType = null;
+      // 
+      // ResultParameterView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.defaultValueGroupBox);
+      this.Controls.Add(this.resultCollectionNameTextBox);
+      this.Controls.Add(this.resultCollectionNameLabel);
+      this.Name = "ResultParameterView";
+      this.Size = new System.Drawing.Size(386, 326);
+      this.Controls.SetChildIndex(this.dataTypeLabel, 0);
+      this.Controls.SetChildIndex(this.dataTypeTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.actualNameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.actualNameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.resultCollectionNameLabel, 0);
+      this.Controls.SetChildIndex(this.resultCollectionNameTextBox, 0);
+      this.Controls.SetChildIndex(this.defaultValueGroupBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.defaultValueGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.TextBox resultCollectionNameTextBox;
+    protected System.Windows.Forms.Label resultCollectionNameLabel;
+    private System.Windows.Forms.GroupBox defaultValueGroupBox;
+    private MainForm.WindowsForms.ViewHost defaultValueViewHost;
+    private System.Windows.Forms.Button removeDefaultValueButton;
+    private System.Windows.Forms.Button setDefaultValueButton;
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultParameterView.cs	(revision 15281)
@@ -0,0 +1,148 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Windows.Forms;
+using HeuristicLab.Common.Resources;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Parameters.Views;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("ResultParameter View")]
+  [Content(typeof(ResultParameter<>), true)]
+  [Content(typeof(IResultParameter<>), false)]
+  public partial class ResultParameterView<T> : LookupParameterView<T> where T : class, IItem {
+    protected TypeSelectorDialog typeSelectorDialog;
+
+    public new IResultParameter<T> Content {
+      get { return (IResultParameter<T>)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ResultParameterView() {
+      InitializeComponent();
+      setDefaultValueButton.Text = string.Empty;
+      setDefaultValueButton.Image = VSImageLibrary.Edit;
+      removeDefaultValueButton.Text = string.Empty;
+      removeDefaultValueButton.Image = VSImageLibrary.Remove;
+      actualNameLabel.Text = "Result Name:";
+      dataTypeLabel.Text = "Result Type:";
+    }
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (typeSelectorDialog != null) typeSelectorDialog.Dispose();
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ResultCollectionNameChanged -= ContentOnResultCollectionNameChanged;
+      Content.DefaultValueChanged -= ContentOnDefaultValueChanged;
+      base.DeregisterContentEvents();
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ResultCollectionNameChanged += ContentOnResultCollectionNameChanged;
+      Content.DefaultValueChanged += ContentOnDefaultValueChanged;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        resultCollectionNameTextBox.Text = "-";
+        defaultValueViewHost.Content = null;
+      } else {
+        resultCollectionNameTextBox.Text = Content.ResultCollectionName;
+        defaultValueViewHost.Content = Content.DefaultValue;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      resultCollectionNameTextBox.Enabled = Content != null;
+      resultCollectionNameTextBox.ReadOnly = ReadOnly;
+      setDefaultValueButton.Enabled = Content != null && !ReadOnly && !Locked;
+      removeDefaultValueButton.Enabled = Content != null && !ReadOnly && !Locked;
+    }
+
+    private void ContentOnDefaultValueChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)ContentOnDefaultValueChanged, sender, e);
+      else defaultValueViewHost.Content = Content.DefaultValue;
+    }
+
+    private void ContentOnResultCollectionNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)ContentOnResultCollectionNameChanged, sender, e);
+      else resultCollectionNameTextBox.Text = Content.ResultCollectionName;
+    }
+
+    private void resultNameTextBox_Validated(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)resultNameTextBox_Validated, sender, e);
+      else Content.ResultCollectionName = resultCollectionNameTextBox.Text;
+    }
+
+    private void setDefaultValueButton_Click(object sender, EventArgs e) {
+      if (typeSelectorDialog == null) {
+        typeSelectorDialog = new TypeSelectorDialog();
+        typeSelectorDialog.Caption = "Select Value";
+        typeSelectorDialog.TypeSelector.Configure(Content.DataType, false, true);
+      }
+      if (typeSelectorDialog.ShowDialog(this) == DialogResult.OK) {
+        try {
+          Content.DefaultValue = (T)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
+        } catch (Exception ex) {
+          ErrorHandling.ShowErrorDialog(this, ex);
+        }
+      }
+    }
+
+    private void removeDefaultValueButton_Click(object sender, EventArgs e) {
+      Content.DefaultValue = null;
+    }
+
+    protected virtual void defaultValueGroupBox_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (!ReadOnly && (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) != null) && Content.DataType.IsAssignableFrom(e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat).GetType())) {
+        if ((e.KeyState & 32) == 32) e.Effect = DragDropEffects.Link;  // ALT key
+        else if ((e.KeyState & 4) == 4) e.Effect = DragDropEffects.Move;  // SHIFT key
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Move)) e.Effect = DragDropEffects.Move;
+        else if (e.AllowedEffect.HasFlag(DragDropEffects.Link)) e.Effect = DragDropEffects.Link;
+      }
+    }
+    protected virtual void defaultValueGroupBox_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        T value = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as T;
+        if (e.Effect.HasFlag(DragDropEffects.Copy)) value = (T)value.Clone();
+        Content.DefaultValue = value;
+      }
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultValueView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ResultView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionColumnConstraintView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionComparisonConstraintView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionConstraintCollectionView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionContentConstraintView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionEqualityConstraintView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionConstraintViews/RunCollectionTypeCompatibilityConstraintView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionModifierListView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBoxPlotView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -463,4 +463,9 @@
     }
 
+	public bool StatisticsVisible {
+		get { return splitContainer.Panel2Collapsed; }
+		set { splitContainer.Panel2Collapsed = value; }
+	}
+	
     public void SetXAxis(string axisName) {
       xAxisComboBox.SelectedItem = axisName;
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -139,4 +139,5 @@
       this.xAxisComboBox.Size = new System.Drawing.Size(400, 21);
       this.xAxisComboBox.TabIndex = 7;
+      this.xAxisComboBox.Sorted = false;
       this.xAxisComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
       // 
@@ -160,4 +161,5 @@
       this.yAxisComboBox.Size = new System.Drawing.Size(400, 21);
       this.yAxisComboBox.TabIndex = 5;
+      this.yAxisComboBox.Sorted = false;
       this.yAxisComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
       // 
@@ -183,4 +185,5 @@
       this.sizeComboBox.Name = "sizeComboBox";
       this.sizeComboBox.Size = new System.Drawing.Size(300, 21);
+      this.sizeComboBox.Sorted = false;
       this.sizeComboBox.TabIndex = 14;
       this.sizeComboBox.SelectedValueChanged += new System.EventHandler(this.AxisComboBox_SelectedValueChanged);
@@ -264,5 +267,5 @@
       this.radioButtonGroup.Controls.Add(this.zoomButton);
       this.radioButtonGroup.Controls.Add(this.selectButton);
-      this.radioButtonGroup.Location = new System.Drawing.Point(3, 704);
+      this.radioButtonGroup.Location = new System.Drawing.Point(6, 679);
       this.radioButtonGroup.Name = "radioButtonGroup";
       this.radioButtonGroup.Size = new System.Drawing.Size(122, 32);
@@ -275,5 +278,5 @@
       this.colorRunsButton.Enabled = false;
       this.colorRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.colorRunsButton.Location = new System.Drawing.Point(131, 713);
+      this.colorRunsButton.Location = new System.Drawing.Point(6, 715);
       this.colorRunsButton.Name = "colorRunsButton";
       this.colorRunsButton.Size = new System.Drawing.Size(21, 21);
@@ -317,5 +320,5 @@
       this.transparencyTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
       this.transparencyTrackBar.LargeChange = 16;
-      this.transparencyTrackBar.Location = new System.Drawing.Point(302, 715);
+      this.transparencyTrackBar.Location = new System.Drawing.Point(177, 717);
       this.transparencyTrackBar.Maximum = 254;
       this.transparencyTrackBar.Name = "transparencyTrackBar";
@@ -331,5 +334,5 @@
       this.hideRunsButton.Enabled = false;
       this.hideRunsButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.hideRunsButton.Location = new System.Drawing.Point(172, 713);
+      this.hideRunsButton.Location = new System.Drawing.Point(47, 715);
       this.hideRunsButton.Name = "hideRunsButton";
       this.hideRunsButton.Size = new System.Drawing.Size(43, 21);
@@ -347,5 +350,5 @@
       this.colorDialogButton.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
       this.colorDialogButton.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.colorDialogButton.Location = new System.Drawing.Point(152, 713);
+      this.colorDialogButton.Location = new System.Drawing.Point(27, 715);
       this.colorDialogButton.Name = "colorDialogButton";
       this.colorDialogButton.Size = new System.Drawing.Size(14, 21);
@@ -390,5 +393,5 @@
       this.transparencyLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
       this.transparencyLabel.AutoSize = true;
-      this.transparencyLabel.Location = new System.Drawing.Point(233, 717);
+      this.transparencyLabel.Location = new System.Drawing.Point(108, 719);
       this.transparencyLabel.Name = "transparencyLabel";
       this.transparencyLabel.Size = new System.Drawing.Size(75, 13);
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionBubbleChartView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -93,4 +93,21 @@
     }
 
+    public string SelectedXAxis {
+      get { return xAxisValue; }
+      set {
+        if (xAxisComboBox.Items.Contains(value)) {
+          xAxisComboBox.SelectedItem = value;
+        }
+      }
+    }
+    public string SelectedYAxis {
+      get { return yAxisValue; }
+      set {
+        if (yAxisComboBox.Items.Contains(value)) {
+          yAxisComboBox.SelectedItem = value;
+        }
+      }
+    }
+
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
@@ -227,10 +244,13 @@
         string[] additionalAxisDimension = Enum.GetNames(typeof(AxisDimension));
         this.xAxisComboBox.Items.AddRange(additionalAxisDimension);
-        this.xAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        var comparer = new HeuristicLab.Common.NaturalStringComparer();
+        var sortedColumnNames = Matrix.ColumnNames.ToArray();
+        sortedColumnNames.StableSort(comparer);
+        this.xAxisComboBox.Items.AddRange(sortedColumnNames);
         this.yAxisComboBox.Items.AddRange(additionalAxisDimension);
-        this.yAxisComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        this.yAxisComboBox.Items.AddRange(sortedColumnNames);
         string[] additionalSizeDimension = Enum.GetNames(typeof(SizeDimension));
         this.sizeComboBox.Items.AddRange(additionalSizeDimension);
-        this.sizeComboBox.Items.AddRange(Matrix.ColumnNames.ToArray());
+        this.sizeComboBox.Items.AddRange(sortedColumnNames);
         this.sizeComboBox.SelectedItem = SizeDimension.Constant.ToString();
 
@@ -415,6 +435,6 @@
         return GetValue(run, sizeDimension);
       } else {
-        int columnIndex = Matrix.ColumnNames.ToList().IndexOf(columnName);
-        IItem value = Content.GetValue(run, columnIndex);
+
+        IItem value = Content.GetValue(run, columnName);
         if (value == null)
           return null;
@@ -431,6 +451,8 @@
         else if (timeSpanValue != null) {
           ret = timeSpanValue.Value.TotalSeconds;
-        } else
+        } else {
+          int columnIndex = Matrix.ColumnNames.ToList().IndexOf(columnName);
           ret = GetCategoricalValue(columnIndex, value.ToString());
+        }
 
         return ret;
@@ -602,24 +624,7 @@
       tooltip = run.Name + System.Environment.NewLine;
 
-      double? xValue = this.GetValue(run, (string)xAxisComboBox.SelectedItem);
-      double? yValue = this.GetValue(run, (string)yAxisComboBox.SelectedItem);
-      double? sizeValue = this.GetValue(run, (string)sizeComboBox.SelectedItem);
-
-      string xString = xValue == null ? string.Empty : xValue.Value.ToString();
-      string yString = yValue == null ? string.Empty : yValue.Value.ToString();
-      string sizeString = sizeValue == null ? string.Empty : sizeValue.Value.ToString();
-
-      //code to handle TimeSpanValues correct
-      int axisDimensionCount = Enum.GetNames(typeof(AxisDimension)).Count();
-      int columnIndex = xAxisComboBox.SelectedIndex - axisDimensionCount;
-      if (xValue.HasValue && columnIndex > 0 && Content.GetValue(0, columnIndex) is TimeSpanValue) {
-        TimeSpan time = TimeSpan.FromSeconds(xValue.Value);
-        xString = string.Format("{0:00}:{1:00}:{2:00.00}", (int)time.TotalHours, time.Minutes, time.Seconds);
-      }
-      columnIndex = yAxisComboBox.SelectedIndex - axisDimensionCount;
-      if (yValue.HasValue && columnIndex > 0 && Content.GetValue(0, columnIndex) is TimeSpanValue) {
-        TimeSpan time = TimeSpan.FromSeconds(yValue.Value);
-        yString = string.Format("{0:00}:{1:00}:{2:00.00}", (int)time.TotalHours, time.Minutes, time.Seconds);
-      }
+      string xString = GetTooltipValue(run, (string)xAxisComboBox.SelectedItem);
+      string yString = GetTooltipValue(run, (string)yAxisComboBox.SelectedItem);
+      string sizeString = GetTooltipValue(run, (string)sizeComboBox.SelectedItem);
 
       tooltip += xAxisComboBox.SelectedItem + " : " + xString + Environment.NewLine;
@@ -628,4 +633,29 @@
 
       return tooltip;
+    }
+
+    private string GetTooltipValue(IRun run, string columnName) {
+      if (columnName == SizeDimension.Constant.ToString())
+        return string.Empty;
+
+      int columnIndex = Matrix.ColumnNames.ToList().IndexOf(columnName);
+
+      //handle non-numeric values correctly
+      if (categoricalMapping.ContainsKey(columnIndex)) {
+        return Content.GetValue(run, columnName).ToString();
+      }
+
+      double? value = GetValue(run, columnName);
+      if (!value.HasValue) return string.Empty;
+
+      string valueString = value.Value.ToString();
+
+      //code to handle TimeSpanValues correctly
+      if (columnIndex > 0 && Content.GetValue(0, columnIndex) is TimeSpanValue) {
+        TimeSpan time = TimeSpan.FromSeconds(value.Value);
+        valueString = string.Format("{0:00}:{1:00}:{2:00.00}", (int)time.TotalHours, time.Minutes, time.Seconds);
+      }
+
+      return valueString;
     }
     #endregion
@@ -726,12 +756,10 @@
     }
     private void hideRunsToolStripMenuItem_Click(object sender, EventArgs e) {
-      //ToList is necessary to prevent lazy evaluation
-      HideRuns(selectedRuns.ToList());
+      HideRuns(selectedRuns);
       //could not use ClearSelectedRuns as the runs are not visible anymore
       selectedRuns.Clear();
     }
     private void hideRunsButton_Click(object sender, EventArgs e) {
-      //ToList is necessary to prevent lazy evaluation
-      HideRuns(selectedRuns.ToList());
+      HideRuns(selectedRuns);
       //could not use ClearSelectedRuns as the runs are not visible anymore
       selectedRuns.Clear();
@@ -739,4 +767,5 @@
 
     private void HideRuns(IEnumerable<IRun> runs) {
+      Content.UpdateOfRunsInProgress = true;
       visibilityConstraint.Active = false;
       if (!Content.Constraints.Contains(visibilityConstraint)) Content.Constraints.Add(visibilityConstraint);
@@ -745,4 +774,5 @@
       }
       visibilityConstraint.Active = true;
+      Content.UpdateOfRunsInProgress = false;
     }
 
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionChartAggregationView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.Designer.cs	(revision 15281)
@@ -0,0 +1,400 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionParameterAnalysisView {
+    /// <summary>
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary>
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form Designer generated code
+
+    /// <summary>
+    /// Required method for Designer support - do not modify
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.stepSizeLabel = new System.Windows.Forms.Label();
+      this.stepSizeTextBox = new System.Windows.Forms.TextBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.logScalingCheckBox = new System.Windows.Forms.CheckBox();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.groupsTreeView = new System.Windows.Forms.TreeView();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+      this.parametersGroupBox = new System.Windows.Forms.GroupBox();
+      this.parametersTreeView = new System.Windows.Forms.TreeView();
+      this.groupsGroupBox = new System.Windows.Forms.GroupBox();
+      this.removeGroupButton = new System.Windows.Forms.Button();
+      this.addGroupButton = new System.Windows.Forms.Button();
+      this.dataRowsGroupBox = new System.Windows.Forms.GroupBox();
+      this.minMaxCheckBox = new System.Windows.Forms.CheckBox();
+      this.medianCheckBox = new System.Windows.Forms.CheckBox();
+      this.quartilesCheckBox = new System.Windows.Forms.CheckBox();
+      this.averageCheckBox = new System.Windows.Forms.CheckBox();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
+      this.splitContainer1.Panel1.SuspendLayout();
+      this.splitContainer1.Panel2.SuspendLayout();
+      this.splitContainer1.SuspendLayout();
+      this.parametersGroupBox.SuspendLayout();
+      this.groupsGroupBox.SuspendLayout();
+      this.dataRowsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.AxisX.IsStartedFromZero = false;
+      chartArea1.AxisX.LabelStyle.Format = "N0";
+      chartArea1.AxisX.MinorGrid.Enabled = true;
+      chartArea1.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+      chartArea1.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.AxisX.ScaleBreakStyle.Enabled = true;
+      chartArea1.AxisX.Title = "Evaluated Solutions";
+      chartArea1.AxisY.LabelStyle.Format = "P0";
+      chartArea1.AxisY.MinorGrid.Enabled = true;
+      chartArea1.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+      chartArea1.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea1.AxisY.Title = "Relative Distance to Best Known Quality";
+      chartArea1.CursorX.Interval = 0D;
+      chartArea1.CursorX.IsUserSelectionEnabled = true;
+      chartArea1.CursorY.Interval = 0D;
+      chartArea1.CursorY.IsUserSelectionEnabled = true;
+      chartArea1.Name = "chartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Cursor = System.Windows.Forms.Cursors.Default;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "legend";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(3, 0);
+      this.chart.Name = "chart";
+      series1.ChartArea = "chartArea";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.FastLine;
+      series1.Legend = "legend";
+      series1.Name = "Series1";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(735, 852);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.Name = "title";
+      this.chart.Titles.Add(title1);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // stepSizeLabel
+      // 
+      this.stepSizeLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.stepSizeLabel.AutoSize = true;
+      this.stepSizeLabel.Location = new System.Drawing.Point(3, 831);
+      this.stepSizeLabel.Name = "stepSizeLabel";
+      this.stepSizeLabel.Size = new System.Drawing.Size(55, 13);
+      this.stepSizeLabel.TabIndex = 1;
+      this.stepSizeLabel.Text = "&Step Size:";
+      // 
+      // stepSizeTextBox
+      // 
+      this.stepSizeTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.stepSizeTextBox.Location = new System.Drawing.Point(82, 828);
+      this.stepSizeTextBox.Name = "stepSizeTextBox";
+      this.stepSizeTextBox.Size = new System.Drawing.Size(100, 20);
+      this.stepSizeTextBox.TabIndex = 2;
+      this.toolTip.SetToolTip(this.stepSizeTextBox, "The step size of evaluated solutions on the x-axis.");
+      this.stepSizeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.stepSizeTextBox_KeyDown);
+      this.stepSizeTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.stepSizeTextBox_Validating);
+      this.stepSizeTextBox.Validated += new System.EventHandler(this.stepSizeTextBox_Validated);
+      // 
+      // logScalingCheckBox
+      // 
+      this.logScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.logScalingCheckBox.AutoSize = true;
+      this.logScalingCheckBox.Location = new System.Drawing.Point(206, 830);
+      this.logScalingCheckBox.Name = "logScalingCheckBox";
+      this.logScalingCheckBox.Size = new System.Drawing.Size(118, 17);
+      this.logScalingCheckBox.TabIndex = 3;
+      this.logScalingCheckBox.Text = "&Logarithmic Scaling";
+      this.toolTip.SetToolTip(this.logScalingCheckBox, "Logarithmic scaling on x-axis.");
+      this.logScalingCheckBox.UseVisualStyleBackColor = true;
+      this.logScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // groupsTreeView
+      // 
+      this.groupsTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupsTreeView.CheckBoxes = true;
+      this.groupsTreeView.HideSelection = false;
+      this.groupsTreeView.Location = new System.Drawing.Point(6, 49);
+      this.groupsTreeView.Name = "groupsTreeView";
+      this.groupsTreeView.ShowRootLines = false;
+      this.groupsTreeView.Size = new System.Drawing.Size(255, 524);
+      this.groupsTreeView.TabIndex = 2;
+      this.groupsTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.groupsTreeView_AfterCheck);
+      this.groupsTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.groupsTreeView_AfterSelect);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.splitContainer1);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.dataRowsGroupBox);
+      this.splitContainer.Panel2.Controls.Add(this.stepSizeTextBox);
+      this.splitContainer.Panel2.Controls.Add(this.stepSizeLabel);
+      this.splitContainer.Panel2.Controls.Add(this.logScalingCheckBox);
+      this.splitContainer.Panel2.Controls.Add(this.chart);
+      this.splitContainer.Size = new System.Drawing.Size(1101, 851);
+      this.splitContainer.SplitterDistance = 273;
+      this.splitContainer.TabIndex = 0;
+      // 
+      // splitContainer1
+      // 
+      this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer1.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer1.Name = "splitContainer1";
+      this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer1.Panel1
+      // 
+      this.splitContainer1.Panel1.Controls.Add(this.parametersGroupBox);
+      // 
+      // splitContainer1.Panel2
+      // 
+      this.splitContainer1.Panel2.Controls.Add(this.groupsGroupBox);
+      this.splitContainer1.Size = new System.Drawing.Size(273, 851);
+      this.splitContainer1.SplitterDistance = 261;
+      this.splitContainer1.TabIndex = 0;
+      // 
+      // parametersGroupBox
+      // 
+      this.parametersGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.parametersGroupBox.Controls.Add(this.parametersTreeView);
+      this.parametersGroupBox.Location = new System.Drawing.Point(3, 3);
+      this.parametersGroupBox.Name = "parametersGroupBox";
+      this.parametersGroupBox.Size = new System.Drawing.Size(267, 255);
+      this.parametersGroupBox.TabIndex = 0;
+      this.parametersGroupBox.TabStop = false;
+      this.parametersGroupBox.Text = "&Parameters";
+      // 
+      // parametersTreeView
+      // 
+      this.parametersTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.parametersTreeView.CheckBoxes = true;
+      this.parametersTreeView.HideSelection = false;
+      this.parametersTreeView.Location = new System.Drawing.Point(6, 19);
+      this.parametersTreeView.Name = "parametersTreeView";
+      this.parametersTreeView.ShowRootLines = false;
+      this.parametersTreeView.Size = new System.Drawing.Size(255, 230);
+      this.parametersTreeView.TabIndex = 0;
+      this.parametersTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.parametersTreeView_AfterCheck);
+      this.parametersTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.parametersTreeView_AfterSelect);
+      // 
+      // groupsGroupBox
+      // 
+      this.groupsGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupsGroupBox.Controls.Add(this.removeGroupButton);
+      this.groupsGroupBox.Controls.Add(this.groupsTreeView);
+      this.groupsGroupBox.Controls.Add(this.addGroupButton);
+      this.groupsGroupBox.Location = new System.Drawing.Point(3, 4);
+      this.groupsGroupBox.Name = "groupsGroupBox";
+      this.groupsGroupBox.Size = new System.Drawing.Size(267, 579);
+      this.groupsGroupBox.TabIndex = 0;
+      this.groupsGroupBox.TabStop = false;
+      this.groupsGroupBox.Text = "&Groups";
+      // 
+      // removeGroupButton
+      // 
+      this.removeGroupButton.Enabled = false;
+      this.removeGroupButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Remove;
+      this.removeGroupButton.Location = new System.Drawing.Point(36, 19);
+      this.removeGroupButton.Name = "removeGroupButton";
+      this.removeGroupButton.Size = new System.Drawing.Size(24, 24);
+      this.removeGroupButton.TabIndex = 1;
+      this.removeGroupButton.UseVisualStyleBackColor = true;
+      this.removeGroupButton.Click += new System.EventHandler(this.removeGroupButton_Click);
+      // 
+      // addGroupButton
+      // 
+      this.addGroupButton.Enabled = false;
+      this.addGroupButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Add;
+      this.addGroupButton.Location = new System.Drawing.Point(6, 19);
+      this.addGroupButton.Name = "addGroupButton";
+      this.addGroupButton.Size = new System.Drawing.Size(24, 24);
+      this.addGroupButton.TabIndex = 0;
+      this.addGroupButton.UseVisualStyleBackColor = true;
+      this.addGroupButton.Click += new System.EventHandler(this.addGroupButton_Click);
+      // 
+      // dataRowsGroupBox
+      // 
+      this.dataRowsGroupBox.Anchor = System.Windows.Forms.AnchorStyles.Right;
+      this.dataRowsGroupBox.Controls.Add(this.minMaxCheckBox);
+      this.dataRowsGroupBox.Controls.Add(this.medianCheckBox);
+      this.dataRowsGroupBox.Controls.Add(this.quartilesCheckBox);
+      this.dataRowsGroupBox.Controls.Add(this.averageCheckBox);
+      this.dataRowsGroupBox.Location = new System.Drawing.Point(744, 395);
+      this.dataRowsGroupBox.Name = "dataRowsGroupBox";
+      this.dataRowsGroupBox.Size = new System.Drawing.Size(77, 111);
+      this.dataRowsGroupBox.TabIndex = 4;
+      this.dataRowsGroupBox.TabStop = false;
+      this.dataRowsGroupBox.Text = "&Data Rows";
+      // 
+      // minMaxCheckBox
+      // 
+      this.minMaxCheckBox.AutoSize = true;
+      this.minMaxCheckBox.Location = new System.Drawing.Point(6, 19);
+      this.minMaxCheckBox.Name = "minMaxCheckBox";
+      this.minMaxCheckBox.Size = new System.Drawing.Size(68, 17);
+      this.minMaxCheckBox.TabIndex = 0;
+      this.minMaxCheckBox.Text = "&Min/Max";
+      this.minMaxCheckBox.UseVisualStyleBackColor = true;
+      this.minMaxCheckBox.CheckedChanged += new System.EventHandler(this.dataRowCheckBox_CheckedChanged);
+      // 
+      // medianCheckBox
+      // 
+      this.medianCheckBox.AutoSize = true;
+      this.medianCheckBox.Checked = true;
+      this.medianCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.medianCheckBox.Location = new System.Drawing.Point(6, 88);
+      this.medianCheckBox.Name = "medianCheckBox";
+      this.medianCheckBox.Size = new System.Drawing.Size(61, 17);
+      this.medianCheckBox.TabIndex = 3;
+      this.medianCheckBox.Text = "M&edian";
+      this.medianCheckBox.UseVisualStyleBackColor = true;
+      this.medianCheckBox.CheckedChanged += new System.EventHandler(this.dataRowCheckBox_CheckedChanged);
+      // 
+      // quartilesCheckBox
+      // 
+      this.quartilesCheckBox.AutoSize = true;
+      this.quartilesCheckBox.Checked = true;
+      this.quartilesCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.quartilesCheckBox.Location = new System.Drawing.Point(6, 42);
+      this.quartilesCheckBox.Name = "quartilesCheckBox";
+      this.quartilesCheckBox.Size = new System.Drawing.Size(59, 17);
+      this.quartilesCheckBox.TabIndex = 1;
+      this.quartilesCheckBox.Text = "&Q1/Q3";
+      this.quartilesCheckBox.UseVisualStyleBackColor = true;
+      this.quartilesCheckBox.CheckedChanged += new System.EventHandler(this.dataRowCheckBox_CheckedChanged);
+      // 
+      // averageCheckBox
+      // 
+      this.averageCheckBox.AutoSize = true;
+      this.averageCheckBox.Location = new System.Drawing.Point(6, 65);
+      this.averageCheckBox.Name = "averageCheckBox";
+      this.averageCheckBox.Size = new System.Drawing.Size(66, 17);
+      this.averageCheckBox.TabIndex = 2;
+      this.averageCheckBox.Text = "&Average";
+      this.averageCheckBox.UseVisualStyleBackColor = true;
+      this.averageCheckBox.CheckedChanged += new System.EventHandler(this.dataRowCheckBox_CheckedChanged);
+      // 
+      // RunCollectionParameterAnalysisView
+      // 
+      this.BackColor = System.Drawing.SystemColors.Window;
+      this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "RunCollectionParameterAnalysisView";
+      this.Size = new System.Drawing.Size(1101, 851);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.Panel2.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.splitContainer1.Panel1.ResumeLayout(false);
+      this.splitContainer1.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
+      this.splitContainer1.ResumeLayout(false);
+      this.parametersGroupBox.ResumeLayout(false);
+      this.groupsGroupBox.ResumeLayout(false);
+      this.dataRowsGroupBox.ResumeLayout(false);
+      this.dataRowsGroupBox.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.Label stepSizeLabel;
+    private System.Windows.Forms.TextBox stepSizeTextBox;
+    private System.Windows.Forms.ToolTip toolTip;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.CheckBox logScalingCheckBox;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.TreeView groupsTreeView;
+    private System.Windows.Forms.GroupBox parametersGroupBox;
+    private System.Windows.Forms.TreeView parametersTreeView;
+    private System.Windows.Forms.CheckBox medianCheckBox;
+    private System.Windows.Forms.CheckBox averageCheckBox;
+    private System.Windows.Forms.CheckBox quartilesCheckBox;
+    private System.Windows.Forms.CheckBox minMaxCheckBox;
+    private System.Windows.Forms.GroupBox dataRowsGroupBox;
+    private System.Windows.Forms.GroupBox groupsGroupBox;
+    private System.Windows.Forms.Button removeGroupButton;
+    private System.Windows.Forms.Button addGroupButton;
+    private System.Windows.Forms.SplitContainer splitContainer1;
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionParameterAnalysisView.cs	(revision 15281)
@@ -0,0 +1,636 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using System.Windows.Forms.DataVisualization.Charting;
+using System.Text;
+using HeuristicLab.Data;
+using System.Drawing;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Parameter Analysis")]
+  [Content(typeof(RunCollection), false)]
+  public sealed partial class RunCollectionParameterAnalysisView : ItemView {
+    #region Colors
+    private static readonly Color[] colors = new[] {
+      Color.FromArgb(0x40, 0x6A, 0xB7),
+      Color.FromArgb(0xB1, 0x6D, 0x01),
+      Color.FromArgb(0x4E, 0x8A, 0x06),
+      Color.FromArgb(0x75, 0x50, 0x7B),
+      Color.FromArgb(0x72, 0x9F, 0xCF),
+      Color.FromArgb(0xA4, 0x00, 0x00),
+      Color.FromArgb(0xAD, 0x7F, 0xA8),
+      Color.FromArgb(0x29, 0x50, 0xCF),
+      Color.FromArgb(0x90, 0xB0, 0x60),
+      Color.FromArgb(0xF5, 0x89, 0x30),
+      Color.FromArgb(0x55, 0x57, 0x53),
+      Color.FromArgb(0xEF, 0x59, 0x59),
+      Color.FromArgb(0xED, 0xD4, 0x30),
+      Color.FromArgb(0x63, 0xC2, 0x16),
+    };
+    #endregion
+
+    private bool suppressUpdates = false;
+    private int stepSize = 1000;
+    private Dictionary<IRun, List<Tuple<int, double>>> runData;
+    private Dictionary<string, ParameterInfo> paramInfos;
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RunCollectionParameterAnalysisView() {
+      InitializeComponent();
+      chart.CustomizeAllChartAreas();
+      stepSizeTextBox.Text = stepSize.ToString();
+      errorProvider.SetIconAlignment(stepSizeTextBox, ErrorIconAlignment.MiddleLeft);
+      errorProvider.SetIconPadding(stepSizeTextBox, 2);
+    }
+
+    #region Content Events
+    protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= Content_ItemsAdded;
+      Content.ItemsRemoved -= Content_ItemsRemoved;
+      Content.CollectionReset -= Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
+      DeregisterRunEvents(Content);
+      base.DeregisterContentEvents();
+    }
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += Content_ItemsAdded;
+      Content.ItemsRemoved += Content_ItemsRemoved;
+      Content.CollectionReset += Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
+      RegisterRunEvents(Content);
+    }
+    private void DeregisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (var run in runs)
+        run.PropertyChanged -= Run_PropertyChanged;
+    }
+    private void RegisterRunEvents(IEnumerable<IRun> runs) {
+      foreach (var run in runs)
+        run.PropertyChanged += Run_PropertyChanged;
+    }
+
+    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.Items);
+    }
+    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      DeregisterRunEvents(e.OldItems);
+      RegisterRunEvents(e.Items);
+    }
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke((Action<object, EventArgs>)Content_UpdateOfRunsInProgressChanged, sender, e);
+      else {
+        suppressUpdates = Content.UpdateOfRunsInProgress;
+        if (suppressUpdates) return;
+        CollectRunData();
+        AnalyzeParameters();
+        UpdateChart();
+      }
+    }
+    private void Run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired)
+        Invoke((Action<object, PropertyChangedEventArgs>)Run_PropertyChanged, sender, e);
+      else {
+        CollectRunData();
+        AnalyzeParameters();
+        UpdateChart();
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      CollectRunData();
+      AnalyzeParameters();
+      UpdateChart();
+    }
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      parametersGroupBox.Enabled = Content != null;
+      groupsGroupBox.Enabled = Content != null;
+      stepSizeTextBox.Enabled = Content != null;
+      logScalingCheckBox.Enabled = Content != null;
+      dataRowsGroupBox.Enabled = Content != null;
+    }
+
+    private void AnalyzeParameters() {
+      paramInfos = new Dictionary<string, ParameterInfo>();
+      if (Content == null) return;
+
+      foreach (var run in runData.Keys) {
+        foreach (var param in run.Parameters) {
+          ParameterInfo info;
+          if (!paramInfos.TryGetValue(param.Key, out info))
+            paramInfos.Add(param.Key, new ParameterInfo(param.Key, param.Value.ToString(), run));
+          else
+            info.AddValue(param.Value.ToString(), run);
+        }
+      }
+
+      // remove irrelevant parameters
+      if (paramInfos.ContainsKey("Seed"))
+        paramInfos.Remove("Seed");
+
+      // remove all parameters which only have a single value
+      var singles = new List<string>();
+      foreach (var paramInfo in paramInfos.Values) {
+        if (paramInfo.Values.Count == 1)
+          singles.Add(paramInfo.Name);
+      }
+      foreach (var single in singles)
+        paramInfos.Remove(single);
+
+      // set color of parameter values
+      int i = 0;
+      foreach (var valueInfo in paramInfos.Values.SelectMany(x => x.Values.Values)) {
+        valueInfo.Color = colors[i];
+        i = (i + 1) % colors.Length;
+      }
+
+      // populate parametersTreeView
+      parametersTreeView.Nodes.Clear();
+      var paramsRoot = new TreeNode("All Runs (" + runData.Keys.Count + ")");
+      paramsRoot.Tag = runData.Keys.ToList();
+      foreach (var paramInfo in paramInfos.Values.OrderBy(x => x.Name)) {
+        var node = new TreeNode(paramInfo.Name + " (" + paramInfo.RunCount + ")");
+        foreach (var value in paramInfo.Values) {
+          var child = new TreeNode(value.Key + " (" + value.Value.RunCount + ")");
+          child.Tag = value.Value;
+          node.Nodes.Add(child);
+        }
+        node.Tag = paramInfo;
+        paramsRoot.Nodes.Add(node);
+      }
+      parametersTreeView.Nodes.Add(paramsRoot);
+      paramsRoot.Expand();
+      paramsRoot.Checked = true;
+      parametersTreeView.SelectedNode = paramsRoot;
+
+      // populate groupsTreeView
+      groupsTreeView.Nodes.Clear();
+      var groupsRoot = new TreeNode("All Runs (" + runData.Keys.Count + ")");
+      groupsRoot.Tag = runData.Keys.ToList();
+      groupsTreeView.Nodes.Add(groupsRoot);
+      groupsRoot.Expand();
+      groupsTreeView.SelectedNode = groupsRoot;
+    }
+    private void CollectRunData() {
+      runData = new Dictionary<IRun, List<Tuple<int, double>>>();
+      if (Content == null) return;
+
+      foreach (var run in Content) {
+        try {
+          IList<Tuple<double, double>> values = (run.Results["QualityPerEvaluations"] as IndexedDataTable<double>).Rows["First-hit Graph"].Values;
+          var bestKnown = (run.Results["BestKnownQuality"] as DoubleValue).Value;
+
+          var data = new List<Tuple<int, double>>();
+          int i = 0;
+          double qual = double.NaN;
+          foreach (var val in values) {
+            while (i * stepSize < val.Item1) {
+              if (!double.IsNaN(qual)) data.Add(Tuple.Create(i * stepSize, qual));
+              i++;
+            }
+            var diff = Math.Abs(bestKnown - val.Item2);
+            qual = bestKnown == 0 ? diff : diff / bestKnown;
+          }
+          runData.Add(run, data);
+        }
+        catch {
+        }
+      }
+    }
+
+    private void UpdateChart() {
+      if (suppressUpdates) return;
+
+      chart.Series.Clear();
+      chart.Legends[0].CustomItems.Clear();
+      chart.Titles[0].Text = string.Empty;
+
+      var checkedNodes = TraverseTreeNodes(parametersTreeView.Nodes)
+                           .Where(x => x.Checked)
+                           .Concat(
+                             TraverseTreeNodes(groupsTreeView.Nodes)
+                               .Where(x => x.Checked)
+                           );
+
+      foreach (var node in checkedNodes) {
+        if (node.Parent == null) {
+          var series = BuildSeries(node.Tag as IEnumerable<IRun>, colors[0]);
+          chart.Titles[0].Text = node.Text;
+          foreach (var s in series)
+            chart.Series.Add(s);
+          var legendItem = new LegendItem();
+          var legendItemInfo = new LegendItemInfo(colors[0], series);
+          legendItem.Color = legendItemInfo.Color;
+          legendItem.BorderColor = Color.Transparent;
+          legendItem.Name = node.Text;
+          legendItem.Tag = legendItemInfo;
+          chart.Legends[0].CustomItems.Add(legendItem);
+        } else if (node.Tag is ParameterInfo) {
+          var paramInfo = node.Tag as ParameterInfo;
+          chart.Titles[0].Text = paramInfo.Name + " (" + paramInfo.RunCount + ")";
+          foreach (var value in paramInfo.Values) {
+            var series = BuildSeries(value.Value.Runs, value.Value.Color);
+            foreach (var s in series)
+              chart.Series.Add(s);
+            var legendItem = new LegendItem();
+            var legendItemInfo = new LegendItemInfo(value.Value.Color, series);
+            legendItem.Color = legendItemInfo.Color;
+            legendItem.BorderColor = Color.Transparent;
+            legendItem.Name = value.Key + " (" + value.Value.RunCount + ")";
+            legendItem.Tag = legendItemInfo;
+            chart.Legends[0].CustomItems.Add(legendItem);
+          }
+        } else if (node.Tag is ParameterValueInfo) {
+          var valueInfo = node.Tag as ParameterValueInfo;
+          var series = BuildSeries(valueInfo.Runs, valueInfo.Color);
+          chart.Titles[0].Text = node.Parent.Text;
+          foreach (var s in series)
+            chart.Series.Add(s);
+          var legendItem = new LegendItem();
+          var legendItemInfo = new LegendItemInfo(valueInfo.Color, series);
+          legendItem.Color = legendItemInfo.Color;
+          legendItem.BorderColor = Color.Transparent;
+          legendItem.Name = node.Text;
+          legendItem.Tag = legendItemInfo;
+          chart.Legends[0].CustomItems.Add(legendItem);
+        } else if (node.Tag is GroupInfo) {
+          var groupInfo = node.Tag as GroupInfo;
+          if (groupInfo.IsParameter) {
+            chart.Titles[0].Text = groupInfo.Text + " (" + groupInfo.Runs.Count + ")";
+            foreach (TreeNode child in node.Nodes) {
+              var childInfo = child.Tag as GroupInfo;
+              var series = BuildSeries(childInfo.Runs, childInfo.Color);
+              foreach (var s in series)
+                chart.Series.Add(s);
+              var legendItem = new LegendItem();
+              var legendItemInfo = new LegendItemInfo(childInfo.Color, series);
+              legendItem.Color = legendItemInfo.Color;
+              legendItem.BorderColor = Color.Transparent;
+              legendItem.Name = childInfo.Text + " (" + childInfo.Runs.Count + ")";
+              legendItem.Tag = legendItemInfo;
+              chart.Legends[0].CustomItems.Add(legendItem);
+            }
+          } else {
+            var parentInfo = node.Parent.Tag as GroupInfo;
+            chart.Titles[0].Text = parentInfo.Text + " (" + parentInfo.Runs.Count + ")";
+            var series = BuildSeries(groupInfo.Runs, groupInfo.Color);
+            foreach (var s in series)
+              chart.Series.Add(s);
+            var legendItem = new LegendItem();
+            var legendItemInfo = new LegendItemInfo(groupInfo.Color, series);
+            legendItem.Color = legendItemInfo.Color;
+            legendItem.BorderColor = Color.Transparent;
+            legendItem.Name = groupInfo.Text + " (" + groupInfo.Runs.Count + ")";
+            legendItem.Tag = legendItemInfo;
+            chart.Legends[0].CustomItems.Add(legendItem);
+          }
+        }
+      }
+    }
+    private void UpdateSeriesVisibility() {
+      foreach (var legendItem in chart.Legends[0].CustomItems) {
+        var legendItemInfo = legendItem.Tag as LegendItemInfo;
+        foreach (var s in legendItemInfo.Series) {
+          if (legendItemInfo.SeriesVisible) {
+            var seriesInfo = s.Tag as SeriesInfo;
+            switch (seriesInfo.Type) {
+              case SeriesTypes.MinMax:
+                s.Color = minMaxCheckBox.Checked ? seriesInfo.Color : Color.Transparent;
+                break;
+              case SeriesTypes.Quartiles:
+                s.Color = quartilesCheckBox.Checked ? seriesInfo.Color : Color.Transparent;
+                break;
+              case SeriesTypes.Median:
+                s.Color = medianCheckBox.Checked ? seriesInfo.Color : Color.Transparent;
+                break;
+              case SeriesTypes.Average:
+                s.Color = averageCheckBox.Checked ? seriesInfo.Color : Color.Transparent;
+                break;
+            }
+          } else {
+            s.Color = Color.Transparent;
+          }
+        }
+      }
+    }
+
+    private IEnumerable<Series> BuildSeries(IEnumerable<IRun> runs, Color color) {
+      var values = new Dictionary<int, List<double>>();
+      foreach (var run in runs) {
+        foreach (var step in runData[run]) {
+          List<double> vals;
+          if (!values.TryGetValue(step.Item1, out vals)) {
+            vals = new List<double>();
+            values.Add(step.Item1, vals);
+          }
+          vals.Add(step.Item2);
+        }
+      }
+
+      List<Series> series = new List<Series>();
+      var minMaxSeries = new Series();
+      var minMaxSeriesInfo = new SeriesInfo(Color.FromArgb(25, color), SeriesTypes.MinMax);
+      minMaxSeries.ChartType = SeriesChartType.Range;
+      minMaxSeries.Color = minMaxCheckBox.Checked ? minMaxSeriesInfo.Color : Color.Transparent;
+      minMaxSeries.IsVisibleInLegend = false;
+      minMaxSeries.Tag = minMaxSeriesInfo;
+      series.Add(minMaxSeries);
+
+      var quartilesSeries = new Series();
+      var quartilesSeriesInfo = new SeriesInfo(Color.FromArgb(50, color), SeriesTypes.Quartiles);
+      quartilesSeries.ChartType = SeriesChartType.Range;
+      quartilesSeries.Color = quartilesCheckBox.Checked ? quartilesSeriesInfo.Color : Color.Transparent;
+      quartilesSeries.IsVisibleInLegend = false;
+      quartilesSeries.Tag = quartilesSeriesInfo;
+      series.Add(quartilesSeries);
+
+      var medianSeries = new Series();
+      var medianSeriesInfo = new SeriesInfo(color, SeriesTypes.Median);
+      medianSeries.ChartType = SeriesChartType.FastLine;
+      medianSeries.Color = medianCheckBox.Checked ? medianSeriesInfo.Color : Color.Transparent;
+      medianSeries.BorderWidth = 3;
+      medianSeries.BorderDashStyle = ChartDashStyle.Solid;
+      medianSeries.IsVisibleInLegend = false;
+      medianSeries.Tag = medianSeriesInfo;
+      series.Add(medianSeries);
+
+      var averageSeries = new Series();
+      var averageSeriesInfo = new SeriesInfo(color, SeriesTypes.Average);
+      averageSeries.ChartType = SeriesChartType.FastLine;
+      averageSeries.Color = averageCheckBox.Checked ? averageSeriesInfo.Color : Color.Transparent;
+      averageSeries.BorderWidth = 3;
+      averageSeries.BorderDashStyle = ChartDashStyle.Dash;
+      averageSeries.IsVisibleInLegend = false;
+      averageSeries.Tag = averageSeriesInfo;
+      series.Add(averageSeries);
+
+      foreach (var point in values.OrderBy(x => x.Key)) {
+        if (point.Value.Count > 0) {
+          minMaxSeries.Points.Add(new DataPoint(point.Key, new double[] { point.Value.Min(), point.Value.Max() }));
+          quartilesSeries.Points.Add(new DataPoint(point.Key, new double[] { point.Value.Quantile(0.25), point.Value.Quantile(0.75) }));
+          medianSeries.Points.Add(new DataPoint(point.Key, point.Value.Median()));
+          averageSeries.Points.Add(new DataPoint(point.Key, point.Value.Average()));
+        }
+      }
+      return series;
+    }
+
+    #region Control Events
+    #region stepSizeTextBox
+    private void stepSizeTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        stepSizeLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        stepSizeTextBox.Text = stepSize.ToString();
+        stepSizeLabel.Select();  // select label to validate data
+      }
+    }
+    private void stepSizeTextBox_Validating(object sender, CancelEventArgs e) {
+      int val;
+      if (!int.TryParse(stepSizeTextBox.Text, out val) || val <= 0) {
+        e.Cancel = true;
+        errorProvider.SetError(stepSizeTextBox, "Invalid Value (Valid Value Format: \"[+]digits\")");
+        stepSizeTextBox.SelectAll();
+      }
+    }
+    private void stepSizeTextBox_Validated(object sender, EventArgs e) {
+      int val = int.Parse(stepSizeTextBox.Text);
+      errorProvider.SetError(stepSizeTextBox, string.Empty);
+      stepSizeTextBox.Text = val.ToString();
+      if (stepSize != val) {
+        stepSize = val;
+        CollectRunData();
+        UpdateChart();
+      }
+    }
+    #endregion
+    #region logScalingCheckBox
+    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
+      chart.ChartAreas[0].AxisX.IsLogarithmic = logScalingCheckBox.Checked;
+    }
+    #endregion
+    #region chart
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        var legendItemInfo = (result.Object as LegendItem).Tag as LegendItemInfo;
+        legendItemInfo.SeriesVisible = !legendItemInfo.SeriesVisible;
+        UpdateSeriesVisibility();
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      switch (result.ChartElementType) {
+        case ChartElementType.LegendItem:
+          Cursor = Cursors.Hand;
+          break;
+        default:
+          Cursor = Cursors.Default;
+          break;
+      }
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var legendItemInfo = legendItem.Tag as LegendItemInfo;
+        legendItem.Color = legendItemInfo.SeriesVisible ? legendItemInfo.Color : Color.Transparent;
+        foreach (LegendCell cell in legendItem.Cells) {
+          cell.ForeColor = legendItemInfo.SeriesVisible ? Color.Black : Color.Gray;
+        }
+      }
+    }
+    #endregion
+    #region parametersTreeView
+    private void parametersTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      addGroupButton.Enabled = (parametersTreeView.SelectedNode != null) && (parametersTreeView.SelectedNode.Parent != null);
+    }
+    private void parametersTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
+      UpdateChart();
+    }
+    #endregion
+    #region groupsTreeView
+    private void groupsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      removeGroupButton.Enabled = (groupsTreeView.SelectedNode != null) && (groupsTreeView.SelectedNode.Parent != null);
+    }
+    private void groupsTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
+      UpdateChart();
+    }
+    #endregion
+    #region addGroupButton, removeGroupButton
+    private void addGroupButton_Click(object sender, EventArgs e) {
+      var group = groupsTreeView.SelectedNode;
+      var param = parametersTreeView.SelectedNode;
+      var groupRuns = group.Parent == null ? group.Tag as IEnumerable<IRun> : (group.Tag as GroupInfo).Runs;
+
+      if (param.Tag is ParameterInfo) {
+        var paramInfo = param.Tag as ParameterInfo;
+        var paramNode = new TreeNode();
+        foreach (var valueInfo in paramInfo.Values.Values) {
+          var valueRuns = groupRuns.Intersect(valueInfo.Runs);
+          var valueNode = new TreeNode(valueInfo.Value + " (" + valueRuns.Count() + ")");
+          valueNode.Tag = new GroupInfo(valueInfo.Value, valueInfo.Color, valueRuns, false);
+          paramNode.Nodes.Add(valueNode);
+        }
+        var paramRuns = groupRuns.Intersect(paramInfo.Runs);
+        paramNode.Text = paramInfo.Name + " (" + paramRuns.Count() + ")";
+        paramNode.Tag = new GroupInfo(paramInfo.Name, Color.Empty, paramRuns, true);
+        group.Nodes.Add(paramNode);
+      } else if (param.Tag is ParameterValueInfo) {
+        var paramInfo = param.Parent.Tag as ParameterInfo;
+        var valueInfo = param.Tag as ParameterValueInfo;
+        var valueRuns = groupRuns.Intersect(valueInfo.Runs);
+        var paramRuns = groupRuns.Intersect(paramInfo.Runs);
+        var paramNode = new TreeNode(paramInfo.Name + " (" + paramRuns.Count() + ")");
+        var valueNode = new TreeNode(valueInfo.Value + " (" + valueRuns.Count() + ")");
+        valueNode.Tag = new GroupInfo(valueInfo.Value, valueInfo.Color, valueRuns, false);
+        paramNode.Tag = new GroupInfo(paramInfo.Name, Color.Empty, paramRuns, true);
+        paramNode.Nodes.Add(valueNode);
+        group.Nodes.Add(paramNode);
+      }
+      groupsTreeView.Nodes[0].Expand();
+    }
+    private void removeGroupButton_Click(object sender, EventArgs e) {
+      if (groupsTreeView.SelectedNode != null)
+        groupsTreeView.SelectedNode.Remove();
+      UpdateChart();
+    }
+    #endregion
+    #region minMaxCheckBox, quartilesCheckBox, averageCheckBox, medianCheckBox
+    private void dataRowCheckBox_CheckedChanged(object sender, EventArgs e) {
+      UpdateSeriesVisibility();
+    }
+    #endregion
+    #endregion
+
+    #region Helpers
+    private IEnumerable<TreeNode> TraverseTreeNodes(TreeNodeCollection nodes) {
+      foreach (var node in nodes.OfType<TreeNode>()) {
+        yield return node;
+        foreach (var child in TraverseTreeNodes(node.Nodes))
+          yield return child;
+      }
+    }
+    #endregion
+
+    #region Inner Types
+    class ParameterInfo {
+      public string Name { get; private set; }
+      public Dictionary<string, ParameterValueInfo> Values { get; private set; }
+      public IEnumerable<IRun> Runs {
+        get { return Values.Values.SelectMany(x => x.Runs); }
+      }
+      public int RunCount {
+        get { return Values.Values.Select(x => x.RunCount).Sum(); }
+      }
+
+      public ParameterInfo(string name, string value, IRun run) {
+        Name = name;
+        Values = new Dictionary<string, ParameterValueInfo>();
+        AddValue(value, run);
+      }
+      public void AddValue(string value, IRun run) {
+        ParameterValueInfo valueInfo;
+        if (!Values.TryGetValue(value, out valueInfo)) {
+          Values.Add(value, new ParameterValueInfo(value, run));
+        } else {
+          valueInfo.Runs.Add(run);
+        }
+      }
+    }
+    class ParameterValueInfo {
+      public string Value { get; private set; }
+      public Color Color { get; set; }
+      public IList<IRun> Runs { get; private set; }
+      public int RunCount {
+        get { return Runs.Count; }
+      }
+
+      public ParameterValueInfo(string value, IRun run) {
+        Value = value;
+        Runs = new List<IRun>();
+        Runs.Add(run);
+      }
+      public ParameterValueInfo(string value, Color color, IRun run) : this(value, run) {
+        Color = color;
+      }
+    }
+    class GroupInfo {
+      public string Text { get; private set; }
+      public Color Color { get; private set; }
+      public IList<IRun> Runs { get; private set; }
+      public bool IsParameter { get; private set; }
+      public GroupInfo(string text, Color color, IEnumerable<IRun> runs, bool isParamter) {
+        Text = text;
+        Color = color;
+        Runs = runs.ToList();
+        IsParameter = isParamter;
+      }
+    }
+    enum SeriesTypes {
+      MinMax,
+      Quartiles,
+      Average,
+      Median
+    }
+    class SeriesInfo {
+      public Color Color { get; private set; }
+      public SeriesTypes Type { get; private set; }
+      public SeriesInfo(Color color, SeriesTypes type) {
+        Color = color;
+        Type = type;
+      }
+    }
+    class LegendItemInfo {
+      public Color Color { get; private set; }
+      public bool SeriesVisible { get; set; }
+      public IEnumerable<Series> Series { get; private set; }
+      public LegendItemInfo(Color color, IEnumerable<Series> series) {
+        Color = color;
+        SeriesVisible = true;
+        Series = series;
+      }
+    }
+    #endregion
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 15281)
@@ -0,0 +1,510 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Optimization.Views {
+  partial class RunCollectionRLDView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.dataTableComboBox = new System.Windows.Forms.ComboBox();
+      this.dataTableLabel = new System.Windows.Forms.Label();
+      this.groupLabel = new System.Windows.Forms.Label();
+      this.groupComboBox = new System.Windows.Forms.ComboBox();
+      this.targetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
+      this.targetsTextBox = new System.Windows.Forms.TextBox();
+      this.targetsLabel = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.addTargetsAsResultButton = new System.Windows.Forms.Button();
+      this.generateTargetsButton = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      this.budgetsLabel = new System.Windows.Forms.Label();
+      this.budgetsTextBox = new System.Windows.Forms.TextBox();
+      this.addBudgetsAsResultButton = new System.Windows.Forms.Button();
+      this.aggregateTargetsCheckBox = new System.Windows.Forms.CheckBox();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.byTargetTabPage = new System.Windows.Forms.TabPage();
+      this.relativeOrAbsoluteComboBox = new System.Windows.Forms.ComboBox();
+      this.targetChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.showLabelsCheckBox = new System.Windows.Forms.CheckBox();
+      this.markerCheckBox = new System.Windows.Forms.CheckBox();
+      this.boundShadingCheckBox = new System.Windows.Forms.CheckBox();
+      this.byCostTabPage = new System.Windows.Forms.TabPage();
+      this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+      this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
+      this.generateBudgetsButton = new System.Windows.Forms.Button();
+      this.byTableTabPage = new System.Windows.Forms.TabPage();
+      this.ertTableView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
+      this.problemComboBox = new System.Windows.Forms.ComboBox();
+      this.problemLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.tabControl.SuspendLayout();
+      this.byTargetTabPage.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).BeginInit();
+      this.byCostTabPage.SuspendLayout();
+      this.byTableTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // dataTableComboBox
+      // 
+      this.dataTableComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.dataTableComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.dataTableComboBox.FormattingEnabled = true;
+      this.dataTableComboBox.Location = new System.Drawing.Point(69, 57);
+      this.dataTableComboBox.Name = "dataTableComboBox";
+      this.dataTableComboBox.Size = new System.Drawing.Size(582, 21);
+      this.dataTableComboBox.TabIndex = 5;
+      this.dataTableComboBox.SelectedIndexChanged += new System.EventHandler(this.dataTableComboBox_SelectedIndexChanged);
+      // 
+      // dataTableLabel
+      // 
+      this.dataTableLabel.AutoSize = true;
+      this.dataTableLabel.Location = new System.Drawing.Point(3, 60);
+      this.dataTableLabel.Name = "dataTableLabel";
+      this.dataTableLabel.Size = new System.Drawing.Size(60, 13);
+      this.dataTableLabel.TabIndex = 4;
+      this.dataTableLabel.Text = "DataTable:";
+      // 
+      // groupLabel
+      // 
+      this.groupLabel.AutoSize = true;
+      this.groupLabel.Location = new System.Drawing.Point(3, 6);
+      this.groupLabel.Name = "groupLabel";
+      this.groupLabel.Size = new System.Drawing.Size(39, 13);
+      this.groupLabel.TabIndex = 0;
+      this.groupLabel.Text = "Group:";
+      // 
+      // groupComboBox
+      // 
+      this.groupComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.groupComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.groupComboBox.FormattingEnabled = true;
+      this.groupComboBox.Location = new System.Drawing.Point(69, 3);
+      this.groupComboBox.Name = "groupComboBox";
+      this.groupComboBox.Size = new System.Drawing.Size(582, 21);
+      this.groupComboBox.TabIndex = 1;
+      this.groupComboBox.SelectedIndexChanged += new System.EventHandler(this.groupComboBox_SelectedIndexChanged);
+      // 
+      // targetLogScalingCheckBox
+      // 
+      this.targetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.targetLogScalingCheckBox.AutoSize = true;
+      this.targetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
+      this.targetLogScalingCheckBox.Name = "targetLogScalingCheckBox";
+      this.targetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+      this.targetLogScalingCheckBox.TabIndex = 6;
+      this.targetLogScalingCheckBox.Text = "logarithmic scaling";
+      this.targetLogScalingCheckBox.UseVisualStyleBackColor = true;
+      this.targetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+      // 
+      // targetsTextBox
+      // 
+      this.targetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.targetsTextBox.Location = new System.Drawing.Point(59, 8);
+      this.targetsTextBox.Name = "targetsTextBox";
+      this.targetsTextBox.Size = new System.Drawing.Size(204, 20);
+      this.targetsTextBox.TabIndex = 1;
+      this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" +
+        "t. The sequence should be monotonous.\r\n\r\nTargets should be separated by semicolo" +
+        "n, tab or space.");
+      this.targetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.targetsTextBox_Validating);
+      // 
+      // targetsLabel
+      // 
+      this.targetsLabel.AutoSize = true;
+      this.targetsLabel.Location = new System.Drawing.Point(6, 11);
+      this.targetsLabel.Name = "targetsLabel";
+      this.targetsLabel.Size = new System.Drawing.Size(46, 13);
+      this.targetsLabel.TabIndex = 0;
+      this.targetsLabel.Text = "Targets:";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.ContainerControl = this;
+      // 
+      // addTargetsAsResultButton
+      // 
+      this.addTargetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.addTargetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+      this.addTargetsAsResultButton.Name = "addTargetsAsResultButton";
+      this.addTargetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+      this.addTargetsAsResultButton.TabIndex = 4;
+      this.addTargetsAsResultButton.Text = "Add as Result";
+      this.addTargetsAsResultButton.UseVisualStyleBackColor = true;
+      this.addTargetsAsResultButton.Click += new System.EventHandler(this.addTargetsAsResultButton_Click);
+      // 
+      // generateTargetsButton
+      // 
+      this.generateTargetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.generateTargetsButton.Location = new System.Drawing.Point(456, 6);
+      this.generateTargetsButton.Name = "generateTargetsButton";
+      this.generateTargetsButton.Size = new System.Drawing.Size(89, 23);
+      this.generateTargetsButton.TabIndex = 3;
+      this.generateTargetsButton.Text = "Generate...";
+      this.generateTargetsButton.UseVisualStyleBackColor = true;
+      this.generateTargetsButton.Click += new System.EventHandler(this.generateTargetsButton_Click);
+      // 
+      // budgetsLabel
+      // 
+      this.budgetsLabel.AutoSize = true;
+      this.budgetsLabel.Location = new System.Drawing.Point(6, 11);
+      this.budgetsLabel.Name = "budgetsLabel";
+      this.budgetsLabel.Size = new System.Drawing.Size(49, 13);
+      this.budgetsLabel.TabIndex = 1;
+      this.budgetsLabel.Text = "Budgets:";
+      // 
+      // budgetsTextBox
+      // 
+      this.budgetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.budgetsTextBox.Location = new System.Drawing.Point(59, 8);
+      this.budgetsTextBox.Name = "budgetsTextBox";
+      this.budgetsTextBox.Size = new System.Drawing.Size(391, 20);
+      this.budgetsTextBox.TabIndex = 6;
+      this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.budgetsTextBox_Validating);
+      // 
+      // addBudgetsAsResultButton
+      // 
+      this.addBudgetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.addBudgetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+      this.addBudgetsAsResultButton.Name = "addBudgetsAsResultButton";
+      this.addBudgetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+      this.addBudgetsAsResultButton.TabIndex = 7;
+      this.addBudgetsAsResultButton.Text = "Add as Result";
+      this.addBudgetsAsResultButton.UseVisualStyleBackColor = true;
+      this.addBudgetsAsResultButton.Click += new System.EventHandler(this.addBudgetsAsResultButton_Click);
+      // 
+      // aggregateTargetsCheckBox
+      // 
+      this.aggregateTargetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.aggregateTargetsCheckBox.AutoSize = true;
+      this.aggregateTargetsCheckBox.Checked = true;
+      this.aggregateTargetsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(374, 10);
+      this.aggregateTargetsCheckBox.Name = "aggregateTargetsCheckBox";
+      this.aggregateTargetsCheckBox.Size = new System.Drawing.Size(74, 17);
+      this.aggregateTargetsCheckBox.TabIndex = 2;
+      this.aggregateTargetsCheckBox.Text = "aggregate";
+      this.aggregateTargetsCheckBox.UseVisualStyleBackColor = true;
+      this.aggregateTargetsCheckBox.CheckedChanged += new System.EventHandler(this.aggregateTargetsCheckBox_CheckedChanged);
+      // 
+      // tabControl
+      // 
+      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tabControl.Controls.Add(this.byTargetTabPage);
+      this.tabControl.Controls.Add(this.byCostTabPage);
+      this.tabControl.Controls.Add(this.byTableTabPage);
+      this.tabControl.Location = new System.Drawing.Point(0, 84);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(654, 413);
+      this.tabControl.TabIndex = 6;
+      // 
+      // byTargetTabPage
+      // 
+      this.byTargetTabPage.Controls.Add(this.relativeOrAbsoluteComboBox);
+      this.byTargetTabPage.Controls.Add(this.targetChart);
+      this.byTargetTabPage.Controls.Add(this.showLabelsCheckBox);
+      this.byTargetTabPage.Controls.Add(this.markerCheckBox);
+      this.byTargetTabPage.Controls.Add(this.boundShadingCheckBox);
+      this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox);
+      this.byTargetTabPage.Controls.Add(this.targetsLabel);
+      this.byTargetTabPage.Controls.Add(this.aggregateTargetsCheckBox);
+      this.byTargetTabPage.Controls.Add(this.targetsTextBox);
+      this.byTargetTabPage.Controls.Add(this.generateTargetsButton);
+      this.byTargetTabPage.Controls.Add(this.addTargetsAsResultButton);
+      this.byTargetTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byTargetTabPage.Name = "byTargetTabPage";
+      this.byTargetTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byTargetTabPage.Size = new System.Drawing.Size(646, 387);
+      this.byTargetTabPage.TabIndex = 0;
+      this.byTargetTabPage.Text = "Performance by Target";
+      this.byTargetTabPage.UseVisualStyleBackColor = true;
+      // 
+      // relativeOrAbsoluteComboBox
+      // 
+      this.relativeOrAbsoluteComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.relativeOrAbsoluteComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.relativeOrAbsoluteComboBox.FormattingEnabled = true;
+      this.relativeOrAbsoluteComboBox.Items.AddRange(new object[] {
+            "relative",
+            "absolute"});
+      this.relativeOrAbsoluteComboBox.Location = new System.Drawing.Point(269, 8);
+      this.relativeOrAbsoluteComboBox.Name = "relativeOrAbsoluteComboBox";
+      this.relativeOrAbsoluteComboBox.Size = new System.Drawing.Size(99, 21);
+      this.relativeOrAbsoluteComboBox.TabIndex = 8;
+      this.relativeOrAbsoluteComboBox.SelectedIndexChanged += new System.EventHandler(this.relativeOrAbsoluteComboBox_SelectedIndexChanged);
+      // 
+      // targetChart
+      // 
+      this.targetChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea2.AxisX.IsStartedFromZero = false;
+      chartArea2.AxisX.MinorGrid.Enabled = true;
+      chartArea2.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+      chartArea2.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea2.AxisY.Maximum = 1D;
+      chartArea2.AxisY.Minimum = 0D;
+      chartArea2.AxisY.MinorGrid.Enabled = true;
+      chartArea2.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+      chartArea2.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      chartArea2.Name = "ChartArea1";
+      this.targetChart.ChartAreas.Add(chartArea2);
+      legend2.Alignment = System.Drawing.StringAlignment.Center;
+      legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend2.Name = "Legend1";
+      this.targetChart.Legends.Add(legend2);
+      this.targetChart.Location = new System.Drawing.Point(6, 34);
+      this.targetChart.Name = "targetChart";
+      this.targetChart.Size = new System.Drawing.Size(634, 324);
+      this.targetChart.SuppressExceptions = true;
+      this.targetChart.TabIndex = 7;
+      this.targetChart.Text = "enhancedChart1";
+      this.targetChart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.targetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.targetChart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // showLabelsCheckBox
+      // 
+      this.showLabelsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.showLabelsCheckBox.AutoSize = true;
+      this.showLabelsCheckBox.Checked = true;
+      this.showLabelsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.showLabelsCheckBox.Location = new System.Drawing.Point(329, 364);
+      this.showLabelsCheckBox.Name = "showLabelsCheckBox";
+      this.showLabelsCheckBox.Size = new System.Drawing.Size(81, 17);
+      this.showLabelsCheckBox.TabIndex = 6;
+      this.showLabelsCheckBox.Text = "show labels";
+      this.showLabelsCheckBox.UseVisualStyleBackColor = true;
+      this.showLabelsCheckBox.CheckedChanged += new System.EventHandler(this.showLabelsCheckBox_CheckedChanged);
+      // 
+      // markerCheckBox
+      // 
+      this.markerCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.markerCheckBox.AutoSize = true;
+      this.markerCheckBox.Location = new System.Drawing.Point(229, 364);
+      this.markerCheckBox.Name = "markerCheckBox";
+      this.markerCheckBox.Size = new System.Drawing.Size(91, 17);
+      this.markerCheckBox.TabIndex = 6;
+      this.markerCheckBox.Text = "show markers";
+      this.markerCheckBox.UseVisualStyleBackColor = true;
+      this.markerCheckBox.CheckedChanged += new System.EventHandler(this.markerCheckBox_CheckedChanged);
+      // 
+      // boundShadingCheckBox
+      // 
+      this.boundShadingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.boundShadingCheckBox.AutoSize = true;
+      this.boundShadingCheckBox.Checked = true;
+      this.boundShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+      this.boundShadingCheckBox.Location = new System.Drawing.Point(127, 364);
+      this.boundShadingCheckBox.Name = "boundShadingCheckBox";
+      this.boundShadingCheckBox.Size = new System.Drawing.Size(96, 17);
+      this.boundShadingCheckBox.TabIndex = 6;
+      this.boundShadingCheckBox.Text = "bound shading";
+      this.boundShadingCheckBox.UseVisualStyleBackColor = true;
+      this.boundShadingCheckBox.CheckedChanged += new System.EventHandler(this.boundShadingCheckBox_CheckedChanged);
+      // 
+      // byCostTabPage
+      // 
+      this.byCostTabPage.Controls.Add(this.byCostViewHost);
+      this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox);
+      this.byCostTabPage.Controls.Add(this.generateBudgetsButton);
+      this.byCostTabPage.Controls.Add(this.budgetsLabel);
+      this.byCostTabPage.Controls.Add(this.addBudgetsAsResultButton);
+      this.byCostTabPage.Controls.Add(this.budgetsTextBox);
+      this.byCostTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byCostTabPage.Name = "byCostTabPage";
+      this.byCostTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byCostTabPage.Size = new System.Drawing.Size(646, 387);
+      this.byCostTabPage.TabIndex = 1;
+      this.byCostTabPage.Text = "Performance by Cost";
+      this.byCostTabPage.UseVisualStyleBackColor = true;
+      // 
+      // byCostViewHost
+      // 
+      this.byCostViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.byCostViewHost.Caption = "View";
+      this.byCostViewHost.Content = null;
+      this.byCostViewHost.Enabled = false;
+      this.byCostViewHost.Location = new System.Drawing.Point(6, 34);
+      this.byCostViewHost.Name = "byCostViewHost";
+      this.byCostViewHost.ReadOnly = false;
+      this.byCostViewHost.Size = new System.Drawing.Size(634, 324);
+      this.byCostViewHost.TabIndex = 12;
+      this.byCostViewHost.ViewsLabelVisible = true;
+      this.byCostViewHost.ViewType = null;
+      // 
+      // budgetLogScalingCheckBox
+      // 
+      this.budgetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+      this.budgetLogScalingCheckBox.AutoSize = true;
+      this.budgetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
+      this.budgetLogScalingCheckBox.Name = "budgetLogScalingCheckBox";
+      this.budgetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+      this.budgetLogScalingCheckBox.TabIndex = 11;
+      this.budgetLogScalingCheckBox.Text = "logarithmic scaling";
+      this.budgetLogScalingCheckBox.UseVisualStyleBackColor = true;
+      this.budgetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+      // 
+      // generateBudgetsButton
+      // 
+      this.generateBudgetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.generateBudgetsButton.Location = new System.Drawing.Point(456, 6);
+      this.generateBudgetsButton.Name = "generateBudgetsButton";
+      this.generateBudgetsButton.Size = new System.Drawing.Size(89, 23);
+      this.generateBudgetsButton.TabIndex = 9;
+      this.generateBudgetsButton.Text = "Generate...";
+      this.generateBudgetsButton.UseVisualStyleBackColor = true;
+      this.generateBudgetsButton.Click += new System.EventHandler(this.generateBudgetsButton_Click);
+      // 
+      // byTableTabPage
+      // 
+      this.byTableTabPage.Controls.Add(this.ertTableView);
+      this.byTableTabPage.Location = new System.Drawing.Point(4, 22);
+      this.byTableTabPage.Name = "byTableTabPage";
+      this.byTableTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.byTableTabPage.Size = new System.Drawing.Size(646, 387);
+      this.byTableTabPage.TabIndex = 2;
+      this.byTableTabPage.Text = "Expected Runtime Tables";
+      this.byTableTabPage.UseVisualStyleBackColor = true;
+      // 
+      // ertTableView
+      // 
+      this.ertTableView.Caption = "StringConvertibleMatrix View";
+      this.ertTableView.Content = null;
+      this.ertTableView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.ertTableView.Location = new System.Drawing.Point(3, 3);
+      this.ertTableView.Name = "ertTableView";
+      this.ertTableView.ReadOnly = false;
+      this.ertTableView.ShowRowsAndColumnsTextBox = false;
+      this.ertTableView.ShowStatisticalInformation = false;
+      this.ertTableView.Size = new System.Drawing.Size(640, 381);
+      this.ertTableView.TabIndex = 0;
+      // 
+      // problemComboBox
+      // 
+      this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.problemComboBox.FormattingEnabled = true;
+      this.problemComboBox.Location = new System.Drawing.Point(69, 30);
+      this.problemComboBox.Name = "problemComboBox";
+      this.problemComboBox.Size = new System.Drawing.Size(582, 21);
+      this.problemComboBox.TabIndex = 3;
+      this.problemComboBox.SelectedIndexChanged += new System.EventHandler(this.problemComboBox_SelectedIndexChanged);
+      // 
+      // problemLabel
+      // 
+      this.problemLabel.AutoSize = true;
+      this.problemLabel.Location = new System.Drawing.Point(3, 33);
+      this.problemLabel.Name = "problemLabel";
+      this.problemLabel.Size = new System.Drawing.Size(48, 13);
+      this.problemLabel.TabIndex = 2;
+      this.problemLabel.Text = "Problem:";
+      // 
+      // RunCollectionRLDView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.tabControl);
+      this.Controls.Add(this.groupComboBox);
+      this.Controls.Add(this.groupLabel);
+      this.Controls.Add(this.problemLabel);
+      this.Controls.Add(this.dataTableLabel);
+      this.Controls.Add(this.problemComboBox);
+      this.Controls.Add(this.dataTableComboBox);
+      this.Name = "RunCollectionRLDView";
+      this.Size = new System.Drawing.Size(654, 497);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.tabControl.ResumeLayout(false);
+      this.byTargetTabPage.ResumeLayout(false);
+      this.byTargetTabPage.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).EndInit();
+      this.byCostTabPage.ResumeLayout(false);
+      this.byCostTabPage.PerformLayout();
+      this.byTableTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox dataTableComboBox;
+    private System.Windows.Forms.Label dataTableLabel;
+    private System.Windows.Forms.Label groupLabel;
+    private System.Windows.Forms.ComboBox groupComboBox;
+    private System.Windows.Forms.CheckBox targetLogScalingCheckBox;
+    private System.Windows.Forms.TextBox targetsTextBox;
+    private System.Windows.Forms.Label targetsLabel;
+    protected System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.Button addTargetsAsResultButton;
+    private System.Windows.Forms.Button generateTargetsButton;
+    private System.Windows.Forms.ToolTip toolTip;
+    private System.Windows.Forms.Button addBudgetsAsResultButton;
+    private System.Windows.Forms.TextBox budgetsTextBox;
+    private System.Windows.Forms.Label budgetsLabel;
+    private System.Windows.Forms.CheckBox aggregateTargetsCheckBox;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage byTargetTabPage;
+    private System.Windows.Forms.TabPage byCostTabPage;
+    private System.Windows.Forms.TabPage byTableTabPage;
+    private System.Windows.Forms.Button generateBudgetsButton;
+    private System.Windows.Forms.CheckBox budgetLogScalingCheckBox;
+    private System.Windows.Forms.Label problemLabel;
+    private System.Windows.Forms.ComboBox problemComboBox;
+    private Data.Views.StringConvertibleMatrixView ertTableView;
+    private Visualization.ChartControlsExtensions.EnhancedChart targetChart;
+    private MainForm.WindowsForms.ViewHost byCostViewHost;
+    private System.Windows.Forms.CheckBox boundShadingCheckBox;
+    private System.Windows.Forms.CheckBox markerCheckBox;
+    private System.Windows.Forms.ComboBox relativeOrAbsoluteComboBox;
+    private System.Windows.Forms.CheckBox showLabelsCheckBox;
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 15281)
@@ -0,0 +1,1405 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Globalization;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Analysis;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Optimization.Views {
+  [View("Run-length Distribution View")]
+  [Content(typeof(RunCollection), false)]
+  public partial class RunCollectionRLDView : ItemView {
+    private List<Series> invisibleTargetSeries;
+
+    private const string AllInstances = "All Instances";
+
+    private static readonly Color[] colors = new[] {
+      Color.FromArgb(0x40, 0x6A, 0xB7),
+      Color.FromArgb(0xB1, 0x6D, 0x01),
+      Color.FromArgb(0x4E, 0x8A, 0x06),
+      Color.FromArgb(0x75, 0x50, 0x7B),
+      Color.FromArgb(0x72, 0x9F, 0xCF),
+      Color.FromArgb(0xA4, 0x00, 0x00),
+      Color.FromArgb(0xAD, 0x7F, 0xA8),
+      Color.FromArgb(0x29, 0x50, 0xCF),
+      Color.FromArgb(0x90, 0xB0, 0x60),
+      Color.FromArgb(0xF5, 0x89, 0x30),
+      Color.FromArgb(0x55, 0x57, 0x53),
+      Color.FromArgb(0xEF, 0x59, 0x59),
+      Color.FromArgb(0xED, 0xD4, 0x30),
+      Color.FromArgb(0x63, 0xC2, 0x16),
+    };
+    private static readonly ChartDashStyle[] lineStyles = new[] {
+      ChartDashStyle.Solid,
+      ChartDashStyle.Dash,
+      ChartDashStyle.DashDot,
+      ChartDashStyle.Dot
+    };
+    private static readonly DataRowVisualProperties.DataRowLineStyle[] hlLineStyles = new[] {
+      DataRowVisualProperties.DataRowLineStyle.Solid,
+      DataRowVisualProperties.DataRowLineStyle.Dash,
+      DataRowVisualProperties.DataRowLineStyle.DashDot,
+      DataRowVisualProperties.DataRowLineStyle.Dot
+    };
+
+    public new RunCollection Content {
+      get { return (RunCollection)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private double[] targets;
+    private double[] budgets;
+    private bool targetsAreRelative = true;
+    private bool showLabelsInTargetChart = true;
+    private readonly BindingList<ProblemInstance> problems;
+
+    private bool suppressUpdates;
+    private readonly IndexedDataTable<double> byCostDataTable;
+    public IndexedDataTable<double> ByCostDataTable {
+      get { return byCostDataTable; }
+    }
+
+    public RunCollectionRLDView() {
+      InitializeComponent();
+      invisibleTargetSeries = new List<Series>();
+
+      targetChart.CustomizeAllChartAreas();
+      targetChart.ChartAreas[0].CursorX.Interval = 1;
+      targetChart.SuppressExceptions = true;
+      byCostDataTable = new IndexedDataTable<double>("ECDF by Cost", "A data table containing the ECDF of function values (relative to best-known).") {
+        VisualProperties = {
+          YAxisTitle = "Proportion of runs",
+          YAxisMinimumFixedValue = 0,
+          YAxisMinimumAuto = false,
+          YAxisMaximumFixedValue = 1,
+          YAxisMaximumAuto = false
+        }
+      };
+      byCostViewHost.Content = byCostDataTable;
+      suppressUpdates = true;
+      relativeOrAbsoluteComboBox.SelectedItem = targetsAreRelative ? "relative" : "absolute";
+      problems = new BindingList<ProblemInstance>();
+      problemComboBox.DataSource = new BindingSource() { DataSource = problems };
+      problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
+      suppressUpdates = false;
+    }
+
+    #region Content events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ItemsAdded += Content_ItemsAdded;
+      Content.ItemsRemoved += Content_ItemsRemoved;
+      Content.CollectionReset += Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged += Content_UpdateOfRunsInProgressChanged;
+      Content.OptimizerNameChanged += Content_AlgorithmNameChanged;
+    }
+    protected override void DeregisterContentEvents() {
+      Content.ItemsAdded -= Content_ItemsAdded;
+      Content.ItemsRemoved -= Content_ItemsRemoved;
+      Content.CollectionReset -= Content_CollectionReset;
+      Content.UpdateOfRunsInProgressChanged -= Content_UpdateOfRunsInProgressChanged;
+      Content.OptimizerNameChanged -= Content_AlgorithmNameChanged;
+      base.DeregisterContentEvents();
+    }
+
+    private void Content_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
+        return;
+      }
+      UpdateGroupAndProblemComboBox();
+      UpdateDataTableComboBox();
+      foreach (var run in e.Items)
+        RegisterRunEvents(run);
+    }
+    private void Content_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsRemoved), sender, e);
+        return;
+      }
+      UpdateGroupAndProblemComboBox();
+      UpdateDataTableComboBox();
+      foreach (var run in e.Items)
+        DeregisterRunEvents(run);
+    }
+    private void Content_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRun> e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_CollectionReset), sender, e);
+        return;
+      }
+      UpdateGroupAndProblemComboBox();
+      UpdateDataTableComboBox();
+      foreach (var run in e.OldItems)
+        DeregisterRunEvents(run);
+    }
+    private void Content_AlgorithmNameChanged(object sender, EventArgs e) {
+      if (InvokeRequired)
+        Invoke(new EventHandler(Content_AlgorithmNameChanged), sender, e);
+      else UpdateCaption();
+    }
+    private void Content_UpdateOfRunsInProgressChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(Content_UpdateOfRunsInProgressChanged), sender, e);
+        return;
+      }
+      suppressUpdates = Content.UpdateOfRunsInProgress;
+      if (!suppressUpdates) {
+        UpdateDataTableComboBox();
+        UpdateGroupAndProblemComboBox();
+        UpdateRuns();
+      }
+    }
+
+    private void RegisterRunEvents(IRun run) {
+      run.PropertyChanged += run_PropertyChanged;
+    }
+    private void DeregisterRunEvents(IRun run) {
+      run.PropertyChanged -= run_PropertyChanged;
+    }
+    private void run_PropertyChanged(object sender, PropertyChangedEventArgs e) {
+      if (suppressUpdates) return;
+      if (InvokeRequired) {
+        Invoke((Action<object, PropertyChangedEventArgs>)run_PropertyChanged, sender, e);
+      } else {
+        if (e.PropertyName == "Visible")
+          UpdateRuns();
+      }
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      dataTableComboBox.Items.Clear();
+      groupComboBox.Items.Clear();
+      targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
+      targetChart.Series.Clear();
+      invisibleTargetSeries.Clear();
+      byCostDataTable.VisualProperties.XAxisLogScale = false;
+      byCostDataTable.Rows.Clear();
+
+      UpdateCaption();
+      if (Content != null) {
+        UpdateGroupAndProblemComboBox();
+        UpdateDataTableComboBox();
+      }
+    }
+
+
+    private void UpdateGroupAndProblemComboBox() {
+      var selectedGroupItem = (string)groupComboBox.SelectedItem;
+
+      var groupings = Content.ParameterNames.OrderBy(x => x).ToArray();
+      groupComboBox.Items.Clear();
+      groupComboBox.Items.Add(AllInstances);
+      groupComboBox.Items.AddRange(groupings);
+      if (selectedGroupItem != null && groupComboBox.Items.Contains(selectedGroupItem)) {
+        groupComboBox.SelectedItem = selectedGroupItem;
+      } else if (groupComboBox.Items.Count > 0) {
+        groupComboBox.SelectedItem = groupComboBox.Items[0];
+      }
+
+      var table = (string)dataTableComboBox.SelectedItem;
+      var problemDict = CalculateBestTargetPerProblemInstance(table);
+
+      var problemTypesDifferent = problemDict.Keys.Select(x => x.ProblemType).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;
+      var problemNamesDifferent = problemDict.Keys.Select(x => x.ProblemName).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;
+      var evaluatorDifferent = problemDict.Keys.Select(x => x.Evaluator).Where(x => !string.IsNullOrEmpty(x)).Distinct().Count() > 1;
+      var maximizationDifferent = problemDict.Keys.Select(x => x.Maximization).Distinct().Count() > 1;
+      var allEqual = !problemTypesDifferent && !problemNamesDifferent && !evaluatorDifferent && !maximizationDifferent;
+
+      var selectedProblemItem = (ProblemInstance)problemComboBox.SelectedItem;
+      problemComboBox.DataSource = null;
+      problemComboBox.Items.Clear();
+      problems.Clear();
+      problems.Add(ProblemInstance.MatchAll);
+      problemComboBox.DataSource = new BindingSource() { DataSource = problems };
+      problemComboBox.DataBindings.DefaultDataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
+      if (problems[0].Equals(selectedProblemItem)) problemComboBox.SelectedItem = problems[0];
+      foreach (var p in problemDict.ToList()) {
+        p.Key.BestKnownQuality = p.Value;
+        p.Key.DisplayProblemType = problemTypesDifferent;
+        p.Key.DisplayProblemName = problemNamesDifferent || allEqual;
+        p.Key.DisplayEvaluator = evaluatorDifferent;
+        p.Key.DisplayMaximization = maximizationDifferent;
+        problems.Add(p.Key);
+        if (p.Key.Equals(selectedProblemItem)) problemComboBox.SelectedItem = p.Key;
+      }
+      SetEnabledStateOfControls();
+    }
+
+    private void UpdateDataTableComboBox() {
+      string selectedItem = (string)dataTableComboBox.SelectedItem;
+
+      dataTableComboBox.Items.Clear();
+      var dataTables = (from run in Content
+                        from result in run.Results
+                        where result.Value is IndexedDataTable<double>
+                        select result.Key).Distinct().ToArray();
+
+      dataTableComboBox.Items.AddRange(dataTables);
+      if (selectedItem != null && dataTableComboBox.Items.Contains(selectedItem)) {
+        dataTableComboBox.SelectedItem = selectedItem;
+      } else if (dataTableComboBox.Items.Count > 0) {
+        dataTableComboBox.SelectedItem = dataTableComboBox.Items[0];
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      groupComboBox.Enabled = Content != null;
+      problemComboBox.Enabled = Content != null && problemComboBox.Items.Count > 1;
+      dataTableComboBox.Enabled = Content != null && dataTableComboBox.Items.Count > 1;
+      addTargetsAsResultButton.Enabled = Content != null && targets != null && dataTableComboBox.SelectedIndex >= 0;
+      addBudgetsAsResultButton.Enabled = Content != null && budgets != null && dataTableComboBox.SelectedIndex >= 0;
+      generateTargetsButton.Enabled = targets != null;
+    }
+
+    private IEnumerable<AlgorithmInstance> GroupRuns() {
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) yield break;
+
+      var selectedGroup = (string)groupComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(selectedGroup)) yield break;
+
+      var selectedProblem = (ProblemInstance)problemComboBox.SelectedItem;
+      if (selectedProblem == null) yield break;
+      
+      foreach (var x in (from r in Content
+                         where (selectedGroup == AllInstances || r.Parameters.ContainsKey(selectedGroup))
+                           && selectedProblem.Match(r)
+                           && r.Results.ContainsKey(table)
+                           && r.Visible
+                         let key = selectedGroup == AllInstances ? AllInstances : r.Parameters[selectedGroup].ToString()
+                         group r by key into g
+                         select new AlgorithmInstance(g.Key, g, problems))) {
+        yield return x;
+      }
+    }
+
+    #region Performance analysis by (multiple) target(s)
+    private void UpdateResultsByTarget() {
+      // necessary to reset log scale -> empty chart cannot use log scaling
+      targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
+      targetChart.Series.Clear();
+      invisibleTargetSeries.Clear();
+      
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+
+      if (targets == null) GenerateDefaultTargets();
+
+      var algInstances = GroupRuns().ToList();
+      if (algInstances.Count == 0) return;
+
+      var xAxisTitles = new HashSet<string>();
+
+      // hits describes the number of target hits at a certain time for a certain group
+      var hits = new Dictionary<string, SortedList<double, int>>();
+      // misses describes the number of target misses after a certain time for a certain group
+      // for instance when a run ends, but has not achieved all targets, misses describes
+      // how many targets have been left open at the point when the run ended
+      var misses = new Dictionary<string, SortedList<double, int>>();
+      var totalRuns = new Dictionary<string, int>();
+
+      var aggregate = aggregateTargetsCheckBox.Checked;
+      double minEff = double.MaxValue, maxEff = double.MinValue;
+      foreach (var alg in algInstances) {
+        var noRuns = 0;
+        SortedList<double, int> epdfHits = null, epdfMisses = null;
+        if (aggregate) {
+          hits[alg.Name] = epdfHits = new SortedList<double, int>();
+          misses[alg.Name] = epdfMisses = new SortedList<double, int>();
+        }
+        foreach (var problem in alg.GetProblemInstances()) {
+          var max = problem.IsMaximization();
+          var absTargets = GetAbsoluteTargets(problem).ToArray();
+          foreach (var run in alg.GetRuns(problem)) {
+            noRuns++;
+            var resultsTable = (IndexedDataTable<double>)run.Results[table];
+            xAxisTitles.Add(resultsTable.VisualProperties.XAxisTitle);
+
+            var efforts = absTargets.Select(t => GetEffortToHitTarget(resultsTable.Rows.First().Values, t, max)).ToArray();
+            minEff = Math.Min(minEff, efforts.Min(x => x.Item2));
+            maxEff = Math.Max(maxEff, efforts.Max(x => x.Item2));
+            for (var idx = 0; idx < efforts.Length; idx++) {
+              var e = efforts[idx];
+              if (!aggregate) {
+                var key = alg.Name + "@" + (targetsAreRelative
+                            ? (targets[idx] * 100).ToString(CultureInfo.CurrentCulture.NumberFormat) + "%"
+                            : targets[idx].ToString(CultureInfo.CurrentCulture.NumberFormat));
+                if (!hits.TryGetValue(key, out epdfHits))
+                  hits[key] = epdfHits = new SortedList<double, int>();
+                if (!misses.TryGetValue(key, out epdfMisses))
+                  misses[key] = epdfMisses = new SortedList<double, int>();
+                totalRuns[key] = noRuns;
+              };
+              var list = e.Item1 ? epdfHits : epdfMisses;
+              int v;
+              if (list.TryGetValue(e.Item2, out v))
+                list[e.Item2] = v + 1;
+              else list[e.Item2] = 1;
+            }
+          }
+        }
+        if (aggregate) totalRuns[alg.Name] = noRuns;
+      }
+
+      UpdateTargetChartAxisXBounds(minEff, maxEff);
+
+      DrawTargetsEcdf(hits, misses, totalRuns);
+
+      if (targets.Length == 1) {
+        if (targetsAreRelative)
+          targetChart.ChartAreas[0].AxisY.Title = "Probability to be " + (targets[0] * 100) + "% worse than best";
+        else targetChart.ChartAreas[0].AxisY.Title = "Probability to reach at least a fitness of " + targets[0];
+      } else targetChart.ChartAreas[0].AxisY.Title = "Proportion of reached targets";
+      targetChart.ChartAreas[0].AxisX.Title = string.Join(" / ", xAxisTitles);
+      targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic();
+      targetChart.ChartAreas[0].CursorY.Interval = 0.05;
+
+      UpdateErtTables(algInstances);
+    }
+
+    private void DrawTargetsEcdf(Dictionary<string, SortedList<double, int>> hits, Dictionary<string, SortedList<double, int>> misses, Dictionary<string, int> noRuns) {
+      var colorCount = 0;
+      var lineStyleCount = 0;
+      
+      var showMarkers = markerCheckBox.Checked;
+      foreach (var list in hits) {
+        var row = new Series(list.Key) {
+          ChartType = SeriesChartType.StepLine,
+          BorderWidth = 3,
+          Color = colors[colorCount],
+          BorderDashStyle = lineStyles[lineStyleCount],
+        };
+        var rowShade = new Series(list.Key + "-range") {
+          IsVisibleInLegend = false,
+          ChartType = SeriesChartType.Range,
+          Color = Color.FromArgb(32, colors[colorCount]),
+          YValuesPerPoint = 2
+        };
+
+        var ecdf = 0.0;
+        var missedecdf = 0.0;
+        var iter = misses[list.Key].GetEnumerator();
+        var moreMisses = iter.MoveNext();
+        var totalTargets = noRuns[list.Key];
+        if (aggregateTargetsCheckBox.Checked) totalTargets *= targets.Length;
+        var movingTargets = totalTargets;
+        var labelPrinted = false;
+        foreach (var h in list.Value) {
+          var prevmissedecdf = missedecdf;
+          while (moreMisses && iter.Current.Key <= h.Key) {
+            if (!labelPrinted && row.Points.Count > 0) {
+              var point = row.Points.Last();
+              if (showLabelsInTargetChart)
+                point.Label = row.Name;
+              point.MarkerStyle = MarkerStyle.Cross;
+              point.MarkerBorderWidth = 1;
+              point.MarkerSize = 10;
+              labelPrinted = true;
+              rowShade.Points.Add(new DataPoint(point.XValue, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets}));
+            }
+            missedecdf += iter.Current.Value;
+            movingTargets -= iter.Current.Value;
+            if (row.Points.Count > 0 && row.Points.Last().XValue == iter.Current.Key) {
+              row.Points.Last().SetValueY(ecdf / movingTargets);
+              row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount]);
+            } else {
+              var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) {
+                Color = Color.FromArgb(255 - (int)Math.Floor(255 * (prevmissedecdf / totalTargets)), colors[colorCount])
+              };
+              if (showMarkers) {
+                dp.MarkerStyle = MarkerStyle.Circle;
+                dp.MarkerBorderWidth = 1;
+                dp.MarkerSize = 5;
+              }
+              row.Points.Add(dp);
+              prevmissedecdf = missedecdf;
+            }
+            if (boundShadingCheckBox.Checked) {
+              if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == iter.Current.Key)
+                rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets);
+              else rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets}));
+            }
+            moreMisses = iter.MoveNext();
+            if (!labelPrinted) {
+              var point = row.Points.Last();
+              if (showLabelsInTargetChart)
+                point.Label = row.Name;
+              point.MarkerStyle = MarkerStyle.Cross;
+              point.MarkerBorderWidth = 1;
+              point.MarkerSize = 10;
+              labelPrinted = true;
+            }
+          }
+          ecdf += h.Value;
+          if (row.Points.Count > 0 && row.Points.Last().XValue == h.Key) {
+            row.Points.Last().SetValueY(ecdf / movingTargets);
+            row.Points.Last().Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount]);
+          } else {
+            var dp = new DataPoint(h.Key, ecdf / movingTargets) {
+              Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount])
+            };
+            if (showMarkers) {
+              dp.MarkerStyle = MarkerStyle.Circle;
+              dp.MarkerBorderWidth = 1;
+              dp.MarkerSize = 5;
+            }
+            row.Points.Add(dp);
+          }
+          if (missedecdf > 0 && boundShadingCheckBox.Checked) {
+            if (rowShade.Points.Count > 0 && rowShade.Points.Last().XValue == h.Key)
+              rowShade.Points.Last().SetValueY(ecdf / totalTargets, (ecdf + missedecdf) / totalTargets);
+            else rowShade.Points.Add(new DataPoint(h.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets}));
+          }
+        }
+
+        while (moreMisses) {
+          // if there are misses beyond the last hit we extend the shaded area
+          missedecdf += iter.Current.Value;
+          var dp = new DataPoint(iter.Current.Key, ecdf / movingTargets) {
+            Color = Color.FromArgb(255 - (int)Math.Floor(255 * (missedecdf / totalTargets)), colors[colorCount])
+          };
+          if (showMarkers) {
+            dp.MarkerStyle = MarkerStyle.Circle;
+            dp.MarkerBorderWidth = 1;
+            dp.MarkerSize = 5;
+          }
+          row.Points.Add(dp);
+          if (boundShadingCheckBox.Checked) {
+            rowShade.Points.Add(new DataPoint(iter.Current.Key, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets}));
+          }
+          moreMisses = iter.MoveNext();
+
+          if (!labelPrinted && row.Points.Count > 0) {
+            var point = row.Points.Last();
+            if (showLabelsInTargetChart)
+              point.Label = row.Name;
+            point.MarkerStyle = MarkerStyle.Cross;
+            point.MarkerBorderWidth = 1;
+            point.MarkerSize = 10;
+            labelPrinted = true;
+          }
+        }
+
+        if (!labelPrinted) {
+          var point = row.Points.Last();
+          if (showLabelsInTargetChart)
+            point.Label = row.Name;
+          point.MarkerStyle = MarkerStyle.Cross;
+          point.MarkerBorderWidth = 1;
+          point.MarkerSize = 10;
+          rowShade.Points.Add(new DataPoint(point.XValue, new[] {ecdf / totalTargets, (ecdf + missedecdf) / totalTargets}));
+          labelPrinted = true;
+        }
+
+        ConfigureSeries(row);
+        targetChart.Series.Add(rowShade);
+        targetChart.Series.Add(row);
+
+        colorCount = (colorCount + 1) % colors.Length;
+        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
+      }
+    }
+
+    private void UpdateTargetChartAxisXBounds(double minEff, double maxEff) {
+      var minZeros = (int)Math.Floor(Math.Log10(minEff));
+      var maxZeros = (int)Math.Floor(Math.Log10(maxEff));
+      var axisMin = (decimal)Math.Pow(10, minZeros);
+      var axisMax = (decimal)Math.Pow(10, maxZeros);
+      if (!targetLogScalingCheckBox.Checked) {
+        var minAdd = (decimal)Math.Pow(10, minZeros - 1) * 2;
+        var maxAdd = (decimal)Math.Pow(10, maxZeros - 1) * 2;
+        while (axisMin + minAdd < (decimal)minEff) axisMin += minAdd;
+        while (axisMax <= (decimal)maxEff) axisMax += maxAdd;
+      } else axisMax = (decimal)Math.Pow(10, (int)Math.Ceiling(Math.Log10(maxEff)));
+      targetChart.ChartAreas[0].AxisX.Minimum = (double)axisMin;
+      targetChart.ChartAreas[0].AxisX.Maximum = (double)axisMax;
+    }
+
+    private IEnumerable<double> GetAbsoluteTargets(ProblemInstance pInstance) {
+      if (!targetsAreRelative) return targets;
+      var maximization = pInstance.IsMaximization();
+      var bestKnown = pInstance.BestKnownQuality;
+      if (double.IsNaN(bestKnown)) throw new ArgumentException("Problem instance does not have a defined best - known quality.");
+      IEnumerable<double> tmp = null;
+      if (bestKnown > 0) {
+        tmp = targets.Select(x => (maximization ? (1 - x) : (1 + x)) * bestKnown);
+      } else if (bestKnown < 0) {
+        tmp = targets.Select(x => (!maximization ? (1 - x) : (1 + x)) * bestKnown);
+      } else {
+        // relative to 0 is impossible
+        tmp = targets;
+      }
+      return tmp;
+    }
+
+    private double[] GetAbsoluteTargetsWorstToBest(ProblemInstance pInstance) {
+      if (double.IsNaN(pInstance.BestKnownQuality)) throw new ArgumentException("Problem instance does not have a defined best-known quality.");
+      var absTargets = GetAbsoluteTargets(pInstance);
+      return (pInstance.IsMaximization()
+        ? absTargets.OrderBy(x => x) : absTargets.OrderByDescending(x => x)).ToArray();
+    }
+
+    private void GenerateDefaultTargets() {
+      targets = new[] { 0.1, 0.095, 0.09, 0.085, 0.08, 0.075, 0.07, 0.065, 0.06, 0.055, 0.05, 0.045, 0.04, 0.035, 0.03, 0.025, 0.02, 0.015, 0.01, 0.005, 0 };
+      SynchronizeTargetTextBox();
+    }
+
+    private Tuple<bool, double> GetEffortToHitTarget(
+        ObservableList<Tuple<double, double>> convergenceGraph,
+        double absTarget, bool maximization) {
+      if (convergenceGraph.Count == 0)
+        throw new ArgumentException("Convergence graph is empty.", "convergenceGraph");
+      
+      var index = convergenceGraph.BinarySearch(Tuple.Create(0.0, absTarget), new TargetComparer(maximization));
+      if (index >= 0) {
+        return Tuple.Create(true, convergenceGraph[index].Item1);
+      } else {
+        index = ~index;
+        if (index >= convergenceGraph.Count)
+          return Tuple.Create(false, convergenceGraph.Last().Item1);
+        return Tuple.Create(true, convergenceGraph[index].Item1);
+      }
+    }
+
+    private void UpdateErtTables(List<AlgorithmInstance> algorithmInstances) {
+      ertTableView.Content = null;
+      var columns = targets.Length + 1;
+      var totalRows = algorithmInstances.Count * algorithmInstances.Max(x => x.GetNumberOfProblemInstances()) + algorithmInstances.Max(x => x.GetNumberOfProblemInstances());
+      var matrix = new StringMatrix(totalRows, columns);
+      var rowNames = new List<string>();
+      matrix.ColumnNames = targets.Select(x => targetsAreRelative ? (100 * x).ToString() + "%" : x.ToString())
+        .Concat(new[] { "#succ" }).ToList();
+      var rowCount = 0;
+
+      var tableName = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(tableName)) return;
+      
+      var problems = algorithmInstances.SelectMany(x => x.GetProblemInstances()).Distinct().ToList();
+
+      foreach (var problem in problems) {
+        var max = problem.IsMaximization();
+        rowNames.Add(problem.ToString());
+        var absTargets = GetAbsoluteTargetsWorstToBest(problem);
+        if (targetsAreRelative) {
+          // print out the absolute target values
+          for (var i = 0; i < absTargets.Length; i++) {
+            matrix[rowCount, i] = absTargets[i].ToString("##,0.0", CultureInfo.CurrentCulture.NumberFormat);
+          }
+        }
+        rowCount++;
+
+        foreach (var alg in algorithmInstances) {
+          rowNames.Add(alg.Name);
+          var runs = alg.GetRuns(problem).ToList();
+          if (runs.Count == 0) {
+            matrix[rowCount, columns - 1] = "N/A";
+            rowCount++;
+            continue;
+          }
+          var result = default(ErtCalculationResult);
+          for (var i = 0; i < absTargets.Length; i++) {
+            result = ExpectedRuntimeHelper.CalculateErt(runs, tableName, absTargets[i], max);
+            matrix[rowCount, i] = result.ToString();
+          }
+          matrix[rowCount, columns - 1] = targets.Length > 0 ? result.SuccessfulRuns + "/" + result.TotalRuns : "-";
+          rowCount++;
+        }
+      }
+      matrix.RowNames = rowNames;
+      ertTableView.Content = matrix;
+      ertTableView.DataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
+    }
+    #endregion
+
+    #region Performance analysis by (multiple) budget(s)
+    private void UpdateResultsByCost() {
+      // necessary to reset log scale -> empty chart cannot use log scaling
+      byCostDataTable.VisualProperties.XAxisLogScale = false;
+      byCostDataTable.Rows.Clear();
+
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+
+      if (budgets == null) GenerateDefaultBudgets(table);
+
+      var algInstances = GroupRuns().ToList();
+      if (algInstances.Count == 0) return;
+
+      var colorCount = 0;
+      var lineStyleCount = 0;
+      
+      foreach (var alg in algInstances) {
+        var hits = new Dictionary<string, SortedList<double, double>>();
+
+        foreach (var problem in alg.GetProblemInstances()) {
+          foreach (var run in alg.GetRuns(problem)) {
+            var resultsTable = (IndexedDataTable<double>)run.Results[table];
+
+            CalculateHitsForEachBudget(hits, resultsTable.Rows.First(), problem, alg.Name);
+          }
+        }
+
+        foreach (var list in hits) {
+          var row = new IndexedDataRow<double>(list.Key) {
+            VisualProperties = {
+              ChartType = DataRowVisualProperties.DataRowChartType.StepLine,
+              LineWidth = 2,
+              Color = colors[colorCount],
+              LineStyle = hlLineStyles[lineStyleCount],
+              StartIndexZero = false
+            }
+          };
+
+          var total = 0.0;
+          var count = list.Value.Count;
+          foreach (var h in list.Value) {
+            total += h.Value;
+            row.Values.Add(Tuple.Create(h.Key, total / (double)count));
+          }
+
+          byCostDataTable.Rows.Add(row);
+        }
+        colorCount = (colorCount + 1) % colors.Length;
+        if (colorCount == 0) lineStyleCount = (lineStyleCount + 1) % lineStyles.Length;
+      }
+
+      byCostDataTable.VisualProperties.XAxisTitle = "Targets to Best-Known Ratio";
+      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
+    }
+
+    private void GenerateDefaultBudgets(string table) {
+      var runs = Content;
+      var min = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Min()).Min();
+      var max = runs.Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Select(y => y.Item1).Max()).Max();
+      var points = 3;
+      budgets = Enumerable.Range(1, points).Select(x => min + (x / (double)points) * (max - min)).ToArray();
+      suppressBudgetsEvents = true;
+      budgetsTextBox.Text = string.Join(" ; ", budgets);
+      suppressBudgetsEvents = false;
+    }
+
+    private void CalculateHitsForEachBudget(Dictionary<string, SortedList<double, double>> hits, IndexedDataRow<double> row, ProblemInstance problem, string groupName) {
+      var max = problem.IsMaximization();
+      var prevIndex = 0;
+      foreach (var b in budgets) {
+        var key = groupName + "-" + b;
+        var index = row.Values.BinarySearch(prevIndex, row.Values.Count - prevIndex, Tuple.Create(b, 0.0), new CostComparer());
+        if (index < 0) {
+          index = ~index;
+          if (index >= row.Values.Count) break; // the run wasn't long enough to use up budget b (or any subsequent larger one)
+        }
+        if (!hits.ContainsKey(key)) hits.Add(key, new SortedList<double, double>());
+        var v = row.Values[index];
+        var relTgt = CalculateRelativeDifference(max, problem.BestKnownQuality, v.Item2) + 1;
+        if (hits[key].ContainsKey(relTgt))
+          hits[key][relTgt]++;
+        else hits[key][relTgt] = 1.0;
+        prevIndex = index;
+      }
+    }
+    #endregion
+
+    private void UpdateCaption() {
+      Caption = Content != null ? Content.OptimizerName + " RLD View" : ViewAttribute.GetViewName(GetType());
+    }
+
+    private void SynchronizeTargetTextBox() {
+      if (InvokeRequired) Invoke((Action)SynchronizeTargetTextBox);
+      else {
+        suppressTargetsEvents = true;
+        try {
+          if (targetsAreRelative)
+            targetsTextBox.Text = string.Join("% ; ", targets.Select(x => x * 100)) + "%";
+          else targetsTextBox.Text = string.Join(" ; ", targets);
+        } finally { suppressTargetsEvents = false; }
+      }
+    }
+
+    private void groupComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateRuns();
+      SetEnabledStateOfControls();
+    }
+    private void problemComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateRuns();
+      SetEnabledStateOfControls();
+    }
+    private void dataTableComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (dataTableComboBox.SelectedIndex >= 0)
+        GenerateDefaultBudgets((string)dataTableComboBox.SelectedItem);
+      UpdateBestKnownQualities();
+      UpdateRuns();
+      SetEnabledStateOfControls();
+    }
+
+    private void logScalingCheckBox_CheckedChanged(object sender, EventArgs e) {
+      UpdateResultsByTarget();
+      byCostDataTable.VisualProperties.XAxisLogScale = byCostDataTable.Rows.Count > 0 && budgetLogScalingCheckBox.Checked;
+    }
+
+    private void boundShadingCheckBox_CheckedChanged(object sender, EventArgs e) {
+      UpdateResultsByTarget();
+    }
+
+    #region Event handlers for target analysis
+    private bool suppressTargetsEvents;
+    private void targetsTextBox_Validating(object sender, CancelEventArgs e) {
+      if (suppressTargetsEvents) return;
+      var targetStrings = targetsTextBox.Text.Split(new[] { '%', ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+      var targetList = new List<decimal>();
+      foreach (var ts in targetStrings) {
+        decimal t;
+        if (!decimal.TryParse(ts, out t)) {
+          errorProvider.SetError(targetsTextBox, "Not all targets can be parsed: " + ts);
+          e.Cancel = true;
+          return;
+        }
+        if (targetsAreRelative)
+          targetList.Add(t / 100);
+        else targetList.Add(t);
+      }
+      if (targetList.Count == 0) {
+        errorProvider.SetError(targetsTextBox, "Give at least one target value!");
+        e.Cancel = true;
+        return;
+      }
+      e.Cancel = false;
+      errorProvider.SetError(targetsTextBox, null);
+      targets = targetsAreRelative ? targetList.Select(x => (double)x).OrderByDescending(x => x).ToArray() : targetList.Select(x => (double)x).ToArray();
+
+      SynchronizeTargetTextBox();
+      UpdateResultsByTarget();
+      SetEnabledStateOfControls();
+    }
+
+    private void aggregateTargetsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+      } finally { ResumeRepaint(true); }
+    }
+
+    private void relativeOrAbsoluteComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (suppressUpdates) return;
+      var pd = (ProblemInstance)problemComboBox.SelectedItem;
+      if (!double.IsNaN(pd.BestKnownQuality)) {
+        var max = pd.IsMaximization();
+        if (targetsAreRelative) targets = GetAbsoluteTargets(pd).ToArray();
+        else {
+          // Rounding to 5 digits since it's certainly appropriate for this application
+          if (pd.BestKnownQuality > 0) {
+            targets = targets.Select(x => Math.Round(max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray();
+          } else if (pd.BestKnownQuality < 0) {
+            targets = targets.Select(x => Math.Round(!max ? 1.0 - (x / pd.BestKnownQuality) : (x / pd.BestKnownQuality) - 1.0, 5)).ToArray();
+          }
+        }
+      }
+      targetsAreRelative = (string)relativeOrAbsoluteComboBox.SelectedItem == "relative";
+      SynchronizeTargetTextBox();
+
+      try {
+        SuspendRepaint();
+        UpdateResultsByTarget();
+      } finally { ResumeRepaint(true); }
+    }
+
+    private void generateTargetsButton_Click(object sender, EventArgs e) {
+      if (targets == null) return;
+      decimal max = 10, min = 0, count = 10;
+      max = (decimal)targets.Max();
+      min = (decimal)targets.Min();
+      count = targets.Length - 1;
+      if (targetsAreRelative) {
+        max *= 100;
+        min *= 100;
+      }
+      using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
+        if (dialog.ShowDialog() == DialogResult.OK) {
+          if (dialog.Values.Any()) {
+            targets = targetsAreRelative
+              ? dialog.Values.OrderByDescending(x => x).Select(x => (double)x / 100.0).ToArray()
+              : dialog.Values.Select(x => (double)x).ToArray();
+
+            SynchronizeTargetTextBox();
+            UpdateResultsByTarget();
+            SetEnabledStateOfControls();
+          }
+        }
+      }
+    }
+
+    private void addTargetsAsResultButton_Click(object sender, EventArgs e) {
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+      
+      foreach (var run in Content) {
+        if (!run.Results.ContainsKey(table)) continue;
+        var resultsTable = (IndexedDataTable<double>)run.Results[table];
+        var values = resultsTable.Rows.First().Values;
+        var pd = new ProblemInstance(run);
+        pd = problems.Single(x => x.Equals(pd));
+        var max = pd.IsMaximization();
+        var absTargets = GetAbsoluteTargetsWorstToBest(pd);
+
+        var prevIndex = 0;
+        for (var i = 0; i < absTargets.Length; i++) {
+          var absTarget = absTargets[i];
+          var index = values.BinarySearch(prevIndex, values.Count - prevIndex, Tuple.Create(0.0, absTarget), new TargetComparer(max));
+          if (index < 0) {
+            index = ~index;
+            if (index >= values.Count) break; // the target (and subsequent ones) wasn't achieved
+          }
+          var target = targetsAreRelative ? (targets[i] * 100) : absTarget;
+          run.Results[table + (targetsAreRelative ? ".RelTarget " : ".AbsTarget ") + target + (targetsAreRelative ? "%" : string.Empty)] = new DoubleValue(values[index].Item1);
+          prevIndex = index;
+        }
+      }
+    }
+
+    private void markerCheckBox_CheckedChanged(object sender, EventArgs e) {
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+      } finally { ResumeRepaint(true); }
+    }
+
+    private void showLabelsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      showLabelsInTargetChart = showLabelsCheckBox.Checked;
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+      } finally { ResumeRepaint(true); }
+    }
+    #endregion
+
+    #region Event handlers for cost analysis
+    private bool suppressBudgetsEvents;
+    private void budgetsTextBox_Validating(object sender, CancelEventArgs e) {
+      if (suppressBudgetsEvents) return;
+      var budgetStrings = budgetsTextBox.Text.Split(new[] { ';', '\t', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+      var budgetList = new List<double>();
+      foreach (var ts in budgetStrings) {
+        double b;
+        if (!double.TryParse(ts, out b)) {
+          errorProvider.SetError(budgetsTextBox, "Not all budgets can be parsed: " + ts);
+          e.Cancel = true;
+          return;
+        }
+        budgetList.Add(b);
+      }
+      if (budgetList.Count == 0) {
+        errorProvider.SetError(budgetsTextBox, "Give at least one budget value!");
+        e.Cancel = true;
+        return;
+      }
+      e.Cancel = false;
+      errorProvider.SetError(budgetsTextBox, null);
+      budgets = budgetList.OrderBy(x => x).ToArray();
+      try {
+        suppressBudgetsEvents = true;
+        budgetsTextBox.Text = string.Join(" ; ", budgets);
+      } finally { suppressBudgetsEvents = false; }
+      UpdateResultsByCost();
+      SetEnabledStateOfControls();
+    }
+
+    private void generateBudgetsButton_Click(object sender, EventArgs e) {
+      decimal max = 1, min = 0, count = 10;
+      if (budgets != null) {
+        max = (decimal)budgets.Max();
+        min = (decimal)budgets.Min();
+        count = budgets.Length;
+      } else if (Content.Count > 0 && dataTableComboBox.SelectedIndex >= 0) {
+        var table = (string)dataTableComboBox.SelectedItem;
+        min = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Min(y => y.Item1)).Min();
+        max = (decimal)Content.Where(x => x.Results.ContainsKey(table)).Select(x => ((IndexedDataTable<double>)x.Results[table]).Rows.First().Values.Max(y => y.Item1)).Max();
+        count = 3;
+      }
+      using (var dialog = new DefineArithmeticProgressionDialog(false, min, max, (max - min) / count)) {
+        if (dialog.ShowDialog() == DialogResult.OK) {
+          if (dialog.Values.Any()) {
+            budgets = dialog.Values.OrderBy(x => x).Select(x => (double)x).ToArray();
+
+            try {
+              suppressBudgetsEvents = true;
+              budgetsTextBox.Text = string.Join(" ; ", budgets);
+            } finally { suppressBudgetsEvents = false; }
+
+            UpdateResultsByCost();
+            SetEnabledStateOfControls();
+          }
+        }
+      }
+    }
+
+    private void addBudgetsAsResultButton_Click(object sender, EventArgs e) {
+      var table = (string)dataTableComboBox.SelectedItem;
+
+      foreach (var run in Content) {
+        if (!run.Results.ContainsKey(table)) continue;
+        var resultsTable = (IndexedDataTable<double>)run.Results[table];
+        var values = resultsTable.Rows.First().Values;
+        var pd = new ProblemInstance(run);
+        pd = problems.Single(x => x.Equals(pd));
+
+        var prevIndex = 0;
+        foreach (var b in budgets) {
+          var index = values.BinarySearch(prevIndex, values.Count - prevIndex, Tuple.Create(b, 0.0), new CostComparer());
+          if (index < 0) {
+            index = ~index;
+            if (index >= values.Count) break; // the run wasn't long enough to use up budget b (or any subsequent larger one)
+          }
+          var v = values[index];
+          var tgt = targetsAreRelative ? CalculateRelativeDifference(pd.IsMaximization(), pd.BestKnownQuality, v.Item2) : v.Item2;
+          run.Results[table + (targetsAreRelative ? ".CostForRelTarget " : ".CostForAbsTarget ") + b] = new DoubleValue(tgt);
+          prevIndex = index;
+        }
+      }
+    }
+    #endregion
+
+    #region Helpers
+    private double CalculateRelativeDifference(bool maximization, double bestKnown, double fit) {
+      if (bestKnown == 0) {
+        // no relative difference with respect to bestKnown possible
+        return maximization ? -fit : fit;
+      }
+      var absDiff = (fit - bestKnown);
+      var relDiff = absDiff / bestKnown;
+      if (maximization) {
+        return bestKnown > 0 ? -relDiff : relDiff;
+      } else {
+        return bestKnown > 0 ? relDiff : -relDiff;
+      }
+    }
+
+    private Dictionary<ProblemInstance, double> CalculateBestTargetPerProblemInstance(string table) {
+      if (table == null) table = string.Empty;
+      return (from r in Content
+              where r.Visible
+              let pd = new ProblemInstance(r)
+              let target = r.Parameters.ContainsKey("BestKnownQuality")
+                           && r.Parameters["BestKnownQuality"] is DoubleValue
+                ? ((DoubleValue)r.Parameters["BestKnownQuality"]).Value
+                : (r.Results.ContainsKey(table) && r.Results[table] is IndexedDataTable<double>
+                  ? ((IndexedDataTable<double>)r.Results[table]).Rows.First().Values.Last().Item2
+                  : double.NaN)
+              group target by pd into g
+              select new { Problem = g.Key, Target = g.Any(x => !double.IsNaN(x)) ? (g.Key.IsMaximization() ? g.Max() : g.Where(x => !double.IsNaN(x)).Min()) : double.NaN })
+        .ToDictionary(x => x.Problem, x => x.Target);
+    }
+
+    private void UpdateRuns() {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateRuns);
+        return;
+      }
+      SuspendRepaint();
+      try {
+        UpdateResultsByTarget();
+        UpdateResultsByCost();
+      } finally { ResumeRepaint(true); }
+    }
+
+    private void UpdateBestKnownQualities() {
+      var table = (string)dataTableComboBox.SelectedItem;
+      if (string.IsNullOrEmpty(table)) return;
+
+      var targetsPerProblem = CalculateBestTargetPerProblemInstance(table);
+      foreach (var pd in problems) {
+        double bkq;
+        if (targetsPerProblem.TryGetValue(pd, out bkq))
+          pd.BestKnownQuality = bkq;
+        else pd.BestKnownQuality = double.NaN;
+      }
+    }
+    #endregion
+
+    private void ConfigureSeries(Series series) {
+      series.SmartLabelStyle.Enabled = showLabelsInTargetChart;
+      series.SmartLabelStyle.AllowOutsidePlotArea = LabelOutsidePlotAreaStyle.No;
+      series.SmartLabelStyle.CalloutLineAnchorCapStyle = LineAnchorCapStyle.None;
+      series.SmartLabelStyle.CalloutLineColor = series.Color;
+      series.SmartLabelStyle.CalloutLineWidth = 2;
+      series.SmartLabelStyle.CalloutStyle = LabelCalloutStyle.Underlined;
+      series.SmartLabelStyle.IsOverlappedHidden = false;
+      series.SmartLabelStyle.MaxMovingDistance = 200;
+      series.ToolTip = series.LegendText + " X = #VALX, Y = #VALY";
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = targetChart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleTargetChartSeriesVisible(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = targetChart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = targetChart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = invisibleTargetSeries.Any(x => x.Name == series.Name);
+          foreach (LegendCell cell in legendItem.Cells) {
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+          }
+        }
+      }
+    }
+
+    private void ToggleTargetChartSeriesVisible(Series series) {
+      var indexList = invisibleTargetSeries.FindIndex(x => x.Name == series.Name);
+      var indexChart = targetChart.Series.IndexOf(series);
+      if (targetChart.Series.Count == 1) targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
+      targetChart.Series.RemoveAt(indexChart);
+      var s = indexList >= 0 ? invisibleTargetSeries[indexList] : new Series(series.Name) {
+        Color = series.Color,
+        ChartType = series.ChartType,
+        BorderWidth = series.BorderWidth,
+        BorderDashStyle = series.BorderDashStyle
+      };
+      if (indexList < 0) {
+        // hide
+        invisibleTargetSeries.Add(series);
+        var shadeSeries = targetChart.Series.FirstOrDefault(x => x.Name == series.Name + "-range");
+        if (shadeSeries != null) {
+          if (targetChart.Series.Count == 1) targetChart.ChartAreas[0].AxisX.IsLogarithmic = false;
+          targetChart.Series.Remove(shadeSeries);
+          invisibleTargetSeries.Add(shadeSeries);
+          indexChart--;
+        }
+      } else {
+        // show
+        invisibleTargetSeries.RemoveAt(indexList);
+        var shadeSeries = invisibleTargetSeries.FirstOrDefault(x => x.Name == series.Name + "-range");
+        if (shadeSeries != null) {
+          invisibleTargetSeries.Remove(shadeSeries);
+          InsertOrAddSeries(indexChart, shadeSeries);
+          indexChart++;
+        }
+      }
+      InsertOrAddSeries(indexChart, s);
+      targetChart.ChartAreas[0].AxisX.IsLogarithmic = CanDisplayLogarithmic();
+    }
+
+    private bool CanDisplayLogarithmic() {
+      return targetLogScalingCheckBox.Checked
+        && targetChart.Series.Count > 0 // must have a series
+        && targetChart.Series.Any(x => x.Points.Count > 0) // at least one series must have points
+        && targetChart.Series.All(s => s.Points.All(p => p.XValue > 0)); // all points must be positive
+    }
+
+    private void InsertOrAddSeries(int index, Series s) {
+      if (targetChart.Series.Count <= index)
+        targetChart.Series.Add(s);
+      else targetChart.Series.Insert(index, s);
+    }
+
+    private class AlgorithmInstance : INotifyPropertyChanged {
+      private string name;
+      public string Name {
+        get { return name; }
+        set {
+          if (name == value) return;
+          name = value;
+          OnPropertyChanged("Name");
+        }
+      }
+
+      private Dictionary<ProblemInstance, List<IRun>> performanceData;
+
+      public int GetNumberOfProblemInstances() {
+        return performanceData.Count;
+      }
+
+      public IEnumerable<ProblemInstance> GetProblemInstances() {
+        return performanceData.Keys;
+      }
+
+      public int GetNumberOfRuns(ProblemInstance p) {
+        if (p == ProblemInstance.MatchAll) return performanceData.Select(x => x.Value.Count).Sum();
+        List<IRun> runs;
+        if (performanceData.TryGetValue(p, out runs))
+          return runs.Count;
+
+        return 0;
+      }
+
+      public IEnumerable<IRun> GetRuns(ProblemInstance p) {
+        if (p == ProblemInstance.MatchAll) return performanceData.SelectMany(x => x.Value);
+        List<IRun> runs;
+        if (performanceData.TryGetValue(p, out runs))
+          return runs;
+
+        return Enumerable.Empty<IRun>();
+      }
+
+      public AlgorithmInstance(string name, IEnumerable<IRun> runs, IEnumerable<ProblemInstance> problems) {
+        this.name = name;
+
+        var pDict = problems.ToDictionary(r => r, _ => new List<IRun>());
+        foreach (var y in runs) {
+          var pd = new ProblemInstance(y);
+          List<IRun> l;
+          if (pDict.TryGetValue(pd, out l)) l.Add(y);
+        }
+        performanceData = pDict.Where(x => x.Value.Count > 0).ToDictionary(x => x.Key, x => x.Value);
+      }
+
+      public override bool Equals(object obj) {
+        var other = obj as AlgorithmInstance;
+        if (other == null) return false;
+        return name == other.name;
+      }
+
+      public override int GetHashCode() {
+        return name.GetHashCode();
+      }
+
+      public event PropertyChangedEventHandler PropertyChanged;
+      protected virtual void OnPropertyChanged(string propertyName = null) {
+        var handler = PropertyChanged;
+        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+      }
+    }
+
+    private class ProblemInstance : INotifyPropertyChanged {
+      private readonly bool matchAll;
+      public static readonly ProblemInstance MatchAll = new ProblemInstance() {
+        ProblemName = "All with Best-Known"
+      };
+
+      private ProblemInstance() {
+        ProblemType = string.Empty;
+        ProblemName = string.Empty;
+        Evaluator = string.Empty;
+        Maximization = string.Empty;
+        DisplayProblemType = false;
+        DisplayProblemName = false;
+        DisplayEvaluator = false;
+        DisplayMaximization = false;
+        matchAll = true;
+        BestKnownQuality = double.NaN;
+      }
+
+      public ProblemInstance(IRun run) {
+        ProblemType = GetStringValueOrEmpty(run, "Problem Type");
+        ProblemName = GetStringValueOrEmpty(run, "Problem Name");
+        Evaluator = GetStringValueOrEmpty(run, "Evaluator");
+        Maximization = GetMaximizationValueOrEmpty(run, "Maximization");
+        DisplayProblemType = !string.IsNullOrEmpty(ProblemType);
+        DisplayProblemName = !string.IsNullOrEmpty(ProblemName);
+        DisplayEvaluator = !string.IsNullOrEmpty(Evaluator);
+        DisplayMaximization = !string.IsNullOrEmpty(Maximization);
+        matchAll = false;
+        BestKnownQuality = GetDoubleValueOrNaN(run, "BestKnownQuality");
+      }
+
+      private bool displayProblemType;
+      public bool DisplayProblemType {
+        get { return displayProblemType; }
+        set {
+          if (displayProblemType == value) return;
+          displayProblemType = value;
+          OnPropertyChanged("DisplayProblemType");
+        }
+      }
+      private string problemType;
+      public string ProblemType {
+        get { return problemType; }
+        set {
+          if (problemType == value) return;
+          problemType = value;
+          OnPropertyChanged("ProblemType");
+        }
+      }
+      private bool displayProblemName;
+      public bool DisplayProblemName {
+        get { return displayProblemName; }
+        set {
+          if (displayProblemName == value) return;
+          displayProblemName = value;
+          OnPropertyChanged("DisplayProblemName");
+        }
+      }
+      private string problemName;
+      public string ProblemName {
+        get { return problemName; }
+        set {
+          if (problemName == value) return;
+          problemName = value;
+          OnPropertyChanged("ProblemName");
+        }
+      }
+      private bool displayEvaluator;
+      public bool DisplayEvaluator {
+        get { return displayEvaluator; }
+        set {
+          if (displayEvaluator == value) return;
+          displayEvaluator = value;
+          OnPropertyChanged("DisplayEvaluator");
+        }
+      }
+      private string evaluator;
+      public string Evaluator {
+        get { return evaluator; }
+        set {
+          if (evaluator == value) return;
+          evaluator = value;
+          OnPropertyChanged("Evaluator");
+        }
+      }
+      private bool displayMaximization;
+      public bool DisplayMaximization {
+        get { return displayMaximization; }
+        set {
+          if (displayMaximization == value) return;
+          displayMaximization = value;
+          OnPropertyChanged("DisplayMaximization");
+        }
+      }
+      private string maximization;
+      public string Maximization {
+        get { return maximization; }
+        set {
+          if (maximization == value) return;
+          maximization = value;
+          OnPropertyChanged("Maximization");
+        }
+      }
+      private double bestKnownQuality;
+      public double BestKnownQuality {
+        get { return bestKnownQuality; }
+        set {
+          if (bestKnownQuality == value) return;
+          bestKnownQuality = value;
+          OnPropertyChanged("BestKnownQuality");
+        }
+      }
+
+      public bool IsMaximization() {
+        return Maximization == "MAX";
+      }
+
+      public bool Match(IRun run) {
+        return matchAll ||
+               GetStringValueOrEmpty(run, "Problem Type") == ProblemType
+               && GetStringValueOrEmpty(run, "Problem Name") == ProblemName
+               && GetStringValueOrEmpty(run, "Evaluator") == Evaluator
+               && GetMaximizationValueOrEmpty(run, "Maximization") == Maximization;
+      }
+
+      private double GetDoubleValueOrNaN(IRun run, string key) {
+        IItem param;
+        if (run.Parameters.TryGetValue(key, out param)) {
+          var dv = param as DoubleValue;
+          return dv != null ? dv.Value : double.NaN;
+        }
+        return double.NaN;
+      }
+
+      private string GetStringValueOrEmpty(IRun run, string key) {
+        IItem param;
+        if (run.Parameters.TryGetValue(key, out param)) {
+          var sv = param as StringValue;
+          return sv != null ? sv.Value : string.Empty;
+        }
+        return string.Empty;
+      }
+
+      private string GetMaximizationValueOrEmpty(IRun run, string key) {
+        IItem param;
+        if (run.Parameters.TryGetValue(key, out param)) {
+          var bv = param as BoolValue;
+          return bv != null ? (bv.Value ? "MAX" : "MIN") : string.Empty;
+        }
+        return string.Empty;
+      }
+
+      public override bool Equals(object obj) {
+        var other = obj as ProblemInstance;
+        if (other == null) return false;
+        return ProblemType == other.ProblemType
+               && ProblemName == other.ProblemName
+               && Evaluator == other.Evaluator
+               && Maximization == other.Maximization;
+      }
+
+      public override int GetHashCode() {
+        return ProblemType.GetHashCode() ^ ProblemName.GetHashCode() ^ Evaluator.GetHashCode() ^ Maximization.GetHashCode();
+      }
+
+      public override string ToString() {
+        return string.Join("  --  ", new[] {
+          (DisplayProblemType ? ProblemType : string.Empty),
+          (DisplayProblemName ? ProblemName : string.Empty),
+          (DisplayEvaluator ? Evaluator : string.Empty),
+          (DisplayMaximization ? Maximization : string.Empty),
+          !double.IsNaN(BestKnownQuality) ? BestKnownQuality.ToString(CultureInfo.CurrentCulture.NumberFormat) : string.Empty }.Where(x => !string.IsNullOrEmpty(x)));
+      }
+
+      public event PropertyChangedEventHandler PropertyChanged;
+      protected virtual void OnPropertyChanged(string propertyName = null) {
+        var handler = PropertyChanged;
+        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
+      }
+    }
+
+    private class CostComparer : Comparer<Tuple<double, double>> {
+      public override int Compare(Tuple<double, double> x, Tuple<double, double> y) {
+        return x.Item1.CompareTo(y.Item1);
+      }
+    }
+
+    private class TargetComparer : Comparer<Tuple<double, double>> {
+      public bool Maximization { get; private set; }
+      public TargetComparer(bool maximization) {
+        Maximization = maximization;
+      }
+
+      public override int Compare(Tuple<double, double> x, Tuple<double, double> y) {
+        return Maximization ? x.Item2.CompareTo(y.Item2) : y.Item2.CompareTo(x.Item2);
+      }
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionTableView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -52,11 +52,14 @@
     }
 
-    public ListView ItemsListView {
-      get { return itemsListView; }
-    }
+    private int EmptyImageIndex { get { return 0; } }
+    private int RunImageIndex { get { return 1; } }
 
     public RunCollectionView() {
       InitializeComponent();
-      itemsGroupBox.Text = "Runs";
+      UpdateGroupBoxText();
+
+      itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
+      itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Class);
+
       itemListViewItemMapping = new Dictionary<IRun, List<ListViewItem>>();
       runCollectionModifiersListView.Evaluator = EvaluateModifications;
@@ -83,10 +86,8 @@
     }
     private void DeregisterItemEvents(IRun item) {
-      item.ItemImageChanged -= new EventHandler(Item_ItemImageChanged);
       item.ToStringChanged -= new EventHandler(Item_ToStringChanged);
       item.PropertyChanged -= Item_PropertyChanged;
     }
     private void RegisterItemEvents(IRun item) {
-      item.ItemImageChanged += new EventHandler(Item_ItemImageChanged);
       item.ToStringChanged += new EventHandler(Item_ToStringChanged);
       item.PropertyChanged += Item_PropertyChanged;
@@ -116,6 +117,7 @@
       itemsListView.Items.Clear();
       itemListViewItemMapping.Clear();
-      RebuildImageList();
       viewHost.Content = null;
+
+      UpdateGroupBoxText();
 
       if (Content != null) {
@@ -129,10 +131,16 @@
           runCollectionModifiersListView.Content = RunCollection.Modifiers;
         }
+
+        ListViewItem[] items = new ListViewItem[Content.Count];
+        int count = 0;
         foreach (IRun item in Content) {
           ListViewItem listViewItem = CreateListViewItem(item);
-          AddListViewItem(listViewItem);
+
           if ((selectedName != null) && item.Name.Equals(selectedName))
             listViewItem.Selected = true;
-        }
+          items[count] = listViewItem;
+          count++;
+        }
+        itemsListView.Items.AddRange(items);
         AdjustListViewColumnSizes();
       } else {
@@ -166,39 +174,36 @@
     }
 
-    private ListViewItem CreateListViewItem(IRun item) {
+    private static readonly string tooltipText = ItemAttribute.GetName(typeof(Run)) + ": " +
+                                    ItemAttribute.GetDescription(typeof(Run));
+    private ListViewItem CreateListViewItem(IRun run) {
       ListViewItem listViewItem = new ListViewItem();
-      if (item == null) {
+      if (run == null) {
         listViewItem.Text = "null";
-        itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
-        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+        listViewItem.ImageIndex = EmptyImageIndex;
+        return listViewItem;
+      }
+
+      listViewItem.Text = run.Name;
+      listViewItem.ToolTipText = tooltipText;
+      listViewItem.ImageIndex = RunImageIndex;
+      listViewItem.Tag = run;
+
+      if (run.Visible) {
+        listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
+        listViewItem.ForeColor = run.Color;
       } else {
-        listViewItem.Text = item.ToString();
-        listViewItem.ToolTipText = item.ItemName + ": " + item.ItemDescription;
-        itemsListView.SmallImageList.Images.Add(item.ItemImage);
-        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
-        listViewItem.Tag = item;
-
-        if (item.Visible) {
-          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Regular);
-          listViewItem.ForeColor = item.Color;
-        } else {
-          listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
-          listViewItem.ForeColor = Color.LightGray;
-        }
-      }
+        listViewItem.Font = new Font(listViewItem.Font, FontStyle.Italic);
+        listViewItem.ForeColor = Color.LightGray;
+      }
+
+      if (!itemListViewItemMapping.ContainsKey(run)) {
+        itemListViewItemMapping.Add(run, new List<ListViewItem>());
+        RegisterItemEvents(run);
+      }
+      itemListViewItemMapping[run].Add(listViewItem);
+
       return listViewItem;
     }
-    private void AddListViewItem(ListViewItem listViewItem) {
-      if (listViewItem == null) throw new ArgumentNullException();
-      itemsListView.Items.Add(listViewItem);
-      IRun run = listViewItem.Tag as IRun;
-      if (run != null) {
-        if (!itemListViewItemMapping.ContainsKey(run)) {
-          itemListViewItemMapping.Add(run, new List<ListViewItem>());
-          RegisterItemEvents(run);
-        }
-        itemListViewItemMapping[run].Add(listViewItem);
-      }
-    }
+
     private void RemoveListViewItem(ListViewItem listViewItem) {
       if (listViewItem == null) throw new ArgumentNullException();
@@ -213,12 +218,5 @@
       listViewItem.Remove();
     }
-    private void UpdateListViewItemImage(ListViewItem listViewItem) {
-      if (listViewItem == null) throw new ArgumentNullException();
-      IRun item = listViewItem.Tag as IRun;
-      int i = listViewItem.ImageIndex;
-      itemsListView.SmallImageList.Images[i] = item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage;
-      listViewItem.ImageIndex = -1;
-      listViewItem.ImageIndex = i;
-    }
+
     private void UpdateListViewItemText(ListViewItem listViewItem) {
       if (listViewItem == null) throw new ArgumentNullException();
@@ -239,4 +237,9 @@
         return listViewItems == null ? Enumerable.Empty<ListViewItem>() : listViewItems;
       }
+    }
+
+    private void UpdateGroupBoxText() {
+      if (Content == null || Content.Count == 0) itemsGroupBox.Text = "Runs";
+      else itemsGroupBox.Text = @"Runs (" + Content.Count + @")";
     }
 
@@ -393,5 +396,6 @@
         RunCollection.UpdateOfRunsInProgress = true;
         RunCollection.Modify();
-      } finally {
+      }
+      finally {
         ReadOnly = false;
         RunCollection.UpdateOfRunsInProgress = false;
@@ -406,11 +410,11 @@
         Invoke(new CollectionItemsChangedEventHandler<IRun>(Content_ItemsAdded), sender, e);
       else {
-        foreach (IRun item in e.Items)
-          AddListViewItem(CreateListViewItem(item));
-
+        var items = e.Items.Select(CreateListViewItem).ToArray();
+        itemsListView.Items.AddRange(items);
         AdjustListViewColumnSizes();
         analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
         clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
         runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+        UpdateGroupBoxText();
       }
     }
@@ -425,8 +429,8 @@
           if (listViewItem != null) RemoveListViewItem(listViewItem);
         }
-        RebuildImageList();
         analyzeRunsToolStripDropDownButton.Enabled = itemsListView.Items.Count > 0;
         clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
         runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+        UpdateGroupBoxText();
       }
     }
@@ -441,7 +445,6 @@
           if (listViewItem != null) RemoveListViewItem(listViewItem);
         }
-        RebuildImageList();
-        foreach (IRun item in e.Items)
-          AddListViewItem(CreateListViewItem(item));
+        var items = e.Items.Select(CreateListViewItem).ToArray();
+        itemsListView.Items.AddRange(items);
 
         AdjustListViewColumnSizes();
@@ -449,4 +452,5 @@
         clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
         runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+        UpdateGroupBoxText();
       }
     }
@@ -456,12 +460,11 @@
         suppressUpdates = RunCollection.UpdateOfRunsInProgress;
         if (!suppressUpdates) {
-          foreach (IRun item in Content) {
-            //remove only the first matching ListViewItem, because the IRun could be contained multiple times in the ItemCollection
-            ListViewItem listViewItem = GetListViewItemsForItem(item).FirstOrDefault();
-            if (listViewItem != null) RemoveListViewItem(listViewItem);
+          foreach (IRun run in Content) {
+            DeregisterItemEvents(run);
           }
-          RebuildImageList();
-          foreach (IRun item in Content)
-            AddListViewItem(CreateListViewItem(item));
+          itemsListView.Items.Clear();
+          itemListViewItemMapping.Clear();
+          var items = Content.Select(CreateListViewItem).ToArray();
+          itemsListView.Items.AddRange(items);
 
           AdjustListViewColumnSizes();
@@ -469,4 +472,5 @@
           clearButton.Enabled = itemsListView.Items.Count > 0 && !Content.IsReadOnly && !ReadOnly;
           runCollectionConstraintCollectionView.ReadOnly = itemsListView.Items.Count == 0;
+          UpdateGroupBoxText();
         }
       }
@@ -475,14 +479,4 @@
 
     #region Item Events
-    private void Item_ItemImageChanged(object sender, EventArgs e) {
-      if (suppressUpdates) return;
-      if (InvokeRequired)
-        Invoke(new EventHandler(Item_ItemImageChanged), sender, e);
-      else {
-        IRun item = (IRun)sender;
-        foreach (ListViewItem listViewItem in GetListViewItemsForItem(item))
-          UpdateListViewItemImage(listViewItem);
-      }
-    }
     private void Item_ToStringChanged(object sender, EventArgs e) {
       if (suppressUpdates) return;
@@ -528,12 +522,4 @@
       }
     }
-    private void RebuildImageList() {
-      itemsListView.SmallImageList.Images.Clear();
-      foreach (ListViewItem listViewItem in itemsListView.Items) {
-        IRun item = listViewItem.Tag as IRun;
-        itemsListView.SmallImageList.Images.Add(item == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : item.ItemImage);
-        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
-      }
-    }
     #endregion
   }
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/RunView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/ThresholdTerminatorView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/TimeLimitRunView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.Designer.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
Index: branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs
===================================================================
--- branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Optimization.Views/3.3/UserDefinedAlgorithmView.cs	(revision 15281)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
