Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionComparisonView.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.
@@ -80,7 +80,6 @@
 
           IClassificationProblemData problemData = Content.ProblemData;
-          var dataset = problemData.Dataset;
           solutions = new List<IClassificationSolution>() { Content };
-          solutions.AddRange(GenerateClassificationSolutions(problemData));
+          solutions.AddRange(GenerateClassificationSolutions().OrderBy(s=>s.Name));
 
           dataGridView.ColumnCount = 4;
@@ -105,9 +104,9 @@
             var trainingIndizes = problemData.TrainingIndices;
             var originalTrainingValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, trainingIndizes);
-            var estimatedTrainingValues = solution.Model.GetEstimatedClassValues(dataset, trainingIndizes);
+            var estimatedTrainingValues = solution.EstimatedTrainingClassValues;
 
             var testIndices = problemData.TestIndices;
             var originalTestValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, testIndices);
-            var estimatedTestValues = solution.Model.GetEstimatedClassValues(dataset, testIndices);
+            var estimatedTestValues = solution.EstimatedTestClassValues;
 
             OnlineCalculatorError errorState;
@@ -126,15 +125,18 @@
     }
 
-    private IEnumerable<IClassificationSolution> GenerateClassificationSolutions(IClassificationProblemData problemData) {
+    protected virtual IEnumerable<IClassificationSolution> GenerateClassificationSolutions() {
+      var problemData = Content.ProblemData;
       var newSolutions = new List<IClassificationSolution>();
       var zeroR = ZeroR.CreateZeroRSolution(problemData);
       zeroR.Name = "ZeroR Classification Solution";
       newSolutions.Add(zeroR);
-      var oneR = OneR.CreateOneRSolution(problemData);
-      oneR.Name = "OneR Classification Solution";
-      newSolutions.Add(oneR);
+      try {
+        var oneR = OneR.CreateOneRSolution(problemData);
+        oneR.Name = "OneR Classification Solution (all variables)";
+        newSolutions.Add(oneR);
+      } catch (NotSupportedException) { } catch (ArgumentException) { }
       try {
         var lda = LinearDiscriminantAnalysis.CreateLinearDiscriminantAnalysisSolution(problemData);
-        lda.Name = "Linear Discriminant Analysis Solution";
+        lda.Name = "Linear Discriminant Analysis Solution (all variables)";
         newSolutions.Add(lda);
       } catch (NotSupportedException) { } catch (ArgumentException) { }
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.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.
@@ -76,4 +76,5 @@
           dataGridView.RowCount = 1;
           dataGridView.ColumnCount = 1;
+          dataGridView.TopLeftHeaderCell.Value = string.Empty;
         } else {
           dataGridView.ColumnCount = Content.ProblemData.Classes + 1;
@@ -91,4 +92,7 @@
           dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
           dataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);
+
+          dataGridView.TopLeftHeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
+          dataGridView.TopLeftHeaderCell.Value = Content.Model.TargetVariable;
 
           FillDataGridView();
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.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.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.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.
@@ -120,5 +120,5 @@
           IEnumerator<double> classValueEnumerator = Content.ProblemData.ClassValues.OrderBy(x => x).GetEnumerator();
           while (classNameEnumerator.MoveNext() && classValueEnumerator.MoveNext()) {
-            Series series = new Series(classNameEnumerator.Current);
+            Series series = new Series(Content.Model.TargetVariable + ": " + classNameEnumerator.Current);
             series.ChartType = SeriesChartType.FastPoint;
             series.Tag = classValueEnumerator.Current;
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.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.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.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.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.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.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.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.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.Designer.cs	(revision 15281)
@@ -0,0 +1,98 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class DensityChart {
+    /// <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 chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Series series1 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // Chart
+      // 
+      this.chart.BackColor = System.Drawing.Color.Transparent;
+      chartArea1.AxisX.Enabled = System.Windows.Forms.DataVisualization.Charting.AxisEnabled.False;
+      chartArea1.AxisX.IsMarginVisible = false;
+      chartArea1.AxisY.Enabled = System.Windows.Forms.DataVisualization.Charting.AxisEnabled.False;
+      chartArea1.AxisY.IsMarginVisible = false;
+      chartArea1.AxisY.Minimum = 0D;
+      chartArea1.BorderColor = System.Drawing.Color.Empty;
+      chartArea1.Name = "ChartArea";
+      chartArea1.Position.Auto = false;
+      chartArea1.Position.Height = 100F;
+      chartArea1.Position.Width = 100F;
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.chart.EnableDoubleClickResetsZoom = false;
+      this.chart.EnableMiddleClickPanning = false;
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      series1.ChartArea = "ChartArea";
+      series1.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.StepLine;
+      series1.Name = "Series1";
+      this.chart.Series.Add(series1);
+      this.chart.Size = new System.Drawing.Size(449, 71);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "Density";
+      // 
+      // DensityChart
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.BackColor = System.Drawing.Color.Transparent;
+      this.Controls.Add(this.chart);
+      this.Name = "DensityChart";
+      this.Size = new System.Drawing.Size(449, 71);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityChart.cs	(revision 15281)
@@ -0,0 +1,85 @@
+﻿#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.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class DensityChart : UserControl {
+    public DensityChart() {
+      InitializeComponent();
+    }
+
+    public void UpdateChart(IList<string> data, double minimumHeight = 0.1) {
+      if (data == null || !data.Any())
+        return;
+      UpdateChartWithBuckets(CalculateBuckets(data));
+    }
+
+
+    public void UpdateChart(IList<double> data, double min, double max, int numBuckets, double minimumHeight = 0.1) {
+      if (data == null || numBuckets < 0 || min > max || max < min)
+        return;
+
+      UpdateChartWithBuckets(CalculateBuckets(data, numBuckets, min, max));
+    }
+
+
+    private void UpdateChartWithBuckets(double[] buckets) {
+      // set minimum height of all non-zero buckets on 10% of maximum
+      double minHeight = buckets.Max() * 0.1;
+      for (int i = 0; i < buckets.Length; i++) {
+        if (buckets[i] >= 1 && buckets[i] < minHeight)
+          buckets[i] = minHeight;
+      }
+
+      var points = chart.Series[0].Points;
+      if (points.Count == buckets.Length) {
+        for (int i = 0; i < buckets.Length; i++)
+          points[i].SetValueY(buckets[i]);
+        chart.ChartAreas[0].RecalculateAxesScale();
+        chart.Refresh();
+      } else {
+        chart.Series[0].Points.DataBindY(buckets);
+      }
+    }
+
+    private double[] CalculateBuckets(IList<double> data, int numBuckets, double min, double max) {
+      var buckets = new double[numBuckets];
+      var bucketSize = (max - min) / numBuckets;
+      if (bucketSize > 0.0) {
+        for (int i = 0; i < data.Count; i++) {
+          int bucketIndex = (int)((data[i] - min) / bucketSize);
+          if (bucketIndex == numBuckets) {
+            bucketIndex--;
+          }
+          if (bucketIndex >= 0 && bucketIndex < buckets.Length)
+            buckets[bucketIndex] += 1.0;
+        }
+      }
+      return buckets;
+    }
+    private double[] CalculateBuckets(IList<string> data) {
+      return data.GroupBy(val => val).OrderBy(g => g.Key).Select(g => (double)g.Count()).Concat(new double[] { 0.0 }).ToArray();
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.Designer.cs	(revision 15281)
@@ -0,0 +1,160 @@
+﻿#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.Algorithms.DataAnalysis.Views {
+  partial class DensityTrackbar {
+    /// <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();
+      this.radioButton = new System.Windows.Forms.RadioButton();
+      this.trackBar = new System.Windows.Forms.TrackBar();
+      this.chart = new HeuristicLab.Problems.DataAnalysis.Views.DensityChart();
+      this.textBox = new System.Windows.Forms.TextBox();
+      this.groupBox = new System.Windows.Forms.GroupBox();
+      this.doubleLimitView = new HeuristicLab.Problems.DataAnalysis.Views.DoubleLimitView();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.trackBar)).BeginInit();
+      this.groupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // radioButton
+      // 
+      this.radioButton.Location = new System.Drawing.Point(6, 11);
+      this.radioButton.Name = "radioButton";
+      this.radioButton.Size = new System.Drawing.Size(132, 17);
+      this.radioButton.TabIndex = 0;
+      this.radioButton.TabStop = true;
+      this.radioButton.Text = "<Name>";
+      this.radioButton.UseVisualStyleBackColor = true;
+      this.radioButton.CheckedChanged += new System.EventHandler(this.radioButton_CheckedChanged);
+      // 
+      // trackBar
+      // 
+      this.trackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.trackBar.BackColor = System.Drawing.Color.White;
+      this.trackBar.LargeChange = 100;
+      this.trackBar.Location = new System.Drawing.Point(144, 10);
+      this.trackBar.Maximum = 1000;
+      this.trackBar.Name = "trackBar";
+      this.trackBar.RightToLeft = System.Windows.Forms.RightToLeft.No;
+      this.trackBar.Size = new System.Drawing.Size(371, 45);
+      this.trackBar.TabIndex = 1;
+      this.trackBar.TickFrequency = 100;
+      this.trackBar.Value = 500;
+      this.trackBar.ValueChanged += new System.EventHandler(this.trackBar_ValueChanged);
+      // 
+      // 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)));
+      this.chart.Location = new System.Drawing.Point(156, 35);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(345, 20);
+      this.chart.TabIndex = 3;
+      // 
+      // textBox
+      // 
+      this.textBox.Location = new System.Drawing.Point(6, 35);
+      this.textBox.Name = "textBox";
+      this.textBox.Size = new System.Drawing.Size(132, 20);
+      this.textBox.TabIndex = 4;
+      this.textBox.Validating += new System.ComponentModel.CancelEventHandler(this.textBox_Validating);
+      this.textBox.Validated += new System.EventHandler(this.textBox_Validated);
+      // 
+      // groupBox
+      // 
+      this.groupBox.Controls.Add(this.radioButton);
+      this.groupBox.Controls.Add(this.doubleLimitView);
+      this.groupBox.Controls.Add(this.chart);
+      this.groupBox.Controls.Add(this.trackBar);
+      this.groupBox.Controls.Add(this.textBox);
+      this.groupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.groupBox.Location = new System.Drawing.Point(0, 0);
+      this.groupBox.Name = "groupBox";
+      this.groupBox.Size = new System.Drawing.Size(678, 62);
+      this.groupBox.TabIndex = 5;
+      this.groupBox.TabStop = false;
+      // 
+      // doubleLimitView
+      // 
+      this.doubleLimitView.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.doubleLimitView.Caption = "DoubleLimit View";
+      this.doubleLimitView.Content = null;
+      this.doubleLimitView.Location = new System.Drawing.Point(521, 10);
+      this.doubleLimitView.Name = "doubleLimitView";
+      this.doubleLimitView.ReadOnly = false;
+      this.doubleLimitView.Size = new System.Drawing.Size(151, 47);
+      this.doubleLimitView.TabIndex = 2;
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // DensityTrackbar
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.groupBox);
+      this.Name = "DensityTrackbar";
+      this.Size = new System.Drawing.Size(678, 62);
+      ((System.ComponentModel.ISupportInitialize)(this.trackBar)).EndInit();
+      this.groupBox.ResumeLayout(false);
+      this.groupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.RadioButton radioButton;
+    private System.Windows.Forms.TrackBar trackBar;
+    private Problems.DataAnalysis.Views.DoubleLimitView doubleLimitView;
+    private HeuristicLab.Problems.DataAnalysis.Views.DensityChart chart;
+    private System.Windows.Forms.TextBox textBox;
+    private System.Windows.Forms.GroupBox groupBox;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DensityTrackbar.cs	(revision 15281)
@@ -0,0 +1,146 @@
+﻿#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.Drawing;
+using System.Globalization;
+using System.Windows.Forms;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.Views {
+  public partial class DensityTrackbar : UserControl {
+
+    public decimal Value {
+      get { return TickToValue(trackBar.Value); }
+      set { trackBar.Value = ValueToTick(value); }
+    }
+    public event EventHandler ValueChanged;
+
+    public bool Checked {
+      get { return radioButton.Checked; }
+      set { radioButton.Checked = value; }
+    }
+    public event EventHandler CheckedChanged;
+
+    public DoubleLimit Limits {
+      get { return doubleLimitView.Content; }
+    }
+    public event EventHandler LimitsChanged;
+
+    private IList<double> trainingValues;
+
+    public DensityTrackbar(string name, DoubleLimit limit, IList<double> trainingValues) {
+      InitializeComponent();
+
+      this.trainingValues = trainingValues;
+
+      doubleLimitView.Content = limit;
+      doubleLimitView.Content.ValueChanged += doubleLimit_ValueChanged;
+
+      textBox.Text = Value.ToString(CultureInfo.InvariantCulture);
+      radioButton.Text = name;
+
+      UpdateDensityChart();
+    }
+
+    public void UpdateTrainingValues(IList<double> trainingValues) {
+      this.trainingValues = trainingValues;
+      UpdateDensityChart();
+    }
+
+    private void UpdateDensityChart() {
+      chart.UpdateChart(trainingValues, Limits.Lower, Limits.Upper,
+        numBuckets: trackBar.Maximum - trackBar.Minimum, minimumHeight: 0.1);
+    }
+
+    #region Event Handlers
+    private void trackBar_ValueChanged(object sender, EventArgs e) {
+      textBox.Text = Value.ToString(CultureInfo.CurrentUICulture);
+      textBox.Update();
+      OnValueChanged();
+    }
+    private void doubleLimit_ValueChanged(object sender, EventArgs e) {
+      UpdateDensityChart();
+      OnLimitsChanged();
+      OnValueChanged();
+    }
+    private void radioButton_CheckedChanged(object sender, EventArgs e) {
+      Checked = radioButton.Checked;
+      trackBar.Enabled = !Checked;
+      textBox.Enabled = !Checked;
+      textBox.Text = Checked ? "Plotted" : Value.ToString(CultureInfo.CurrentUICulture);
+      radioButton.BackColor = Checked ? SystemColors.ActiveCaption : SystemColors.Control;
+      OnCheckedChanged();
+    }
+    protected override void OnTextChanged(EventArgs e) {
+      base.OnTextChanged(e);
+      radioButton.Text = Text;
+    }
+
+    private void textBox_Validating(object sender, CancelEventArgs e) {
+      if (Checked) return;
+      decimal number;
+      if (!decimal.TryParse(textBox.Text, NumberStyles.Any, CultureInfo.CurrentUICulture.NumberFormat, out number)) {
+        e.Cancel = true;
+        errorProvider.SetIconAlignment(textBox, ErrorIconAlignment.MiddleLeft);
+        errorProvider.SetIconPadding(textBox, 2);
+        errorProvider.SetError(textBox, "Illegal number format");
+      }
+    }
+
+    private void textBox_Validated(object sender, EventArgs e) {
+      if (Checked) return;
+      errorProvider.SetError(textBox, string.Empty);
+      Value = decimal.Parse(textBox.Text, NumberStyles.Any, CultureInfo.CurrentUICulture.NumberFormat);
+    }
+    #endregion
+
+    protected virtual void OnValueChanged() {
+      if (ValueChanged != null)
+        ValueChanged(this, EventArgs.Empty);
+    }
+    protected virtual void OnCheckedChanged() {
+      if (CheckedChanged != null)
+        CheckedChanged(this, EventArgs.Empty);
+    }
+    protected virtual void OnLimitsChanged() {
+      if (LimitsChanged != null)
+        LimitsChanged(this, EventArgs.Empty);
+    }
+
+    #region Helpers
+    private decimal TickToValue(int tick) {
+      return TickToValue(tick, trackBar.Maximum - trackBar.Minimum, (decimal)Limits.Lower, (decimal)Limits.Upper);
+    }
+    private int ValueToTick(decimal value) {
+      return ValueToTick(value, trackBar.Maximum - trackBar.Minimum, (decimal)Limits.Lower, (decimal)Limits.Upper);
+    }
+    private static decimal TickToValue(int tick, int numberOfTicks, decimal lower, decimal upper) {
+      return lower + (upper - lower) * tick / numberOfTicks;
+    }
+    private static int ValueToTick(decimal value, int numberOfTicks, decimal lower, decimal upper) {
+      return (int)((value - lower) / ((upper - lower) / numberOfTicks));
+    }
+    #endregion
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.Designer.cs	(revision 15281)
@@ -0,0 +1,69 @@
+﻿#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.Problems.DataAnalysis.Views {
+  public partial class DoubleLimitView {
+    /// <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.SuspendLayout();
+      // 
+      // Item1Label
+      // 
+      this.Item1Label.Size = new System.Drawing.Size(39, 13);
+      this.Item1Label.Text = "Lower:";
+      // 
+      // Item2Label
+      // 
+      this.Item2Label.Size = new System.Drawing.Size(39, 13);
+      this.Item2Label.Text = "Upper:";
+      // 
+      // DoubleLimitView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Name = "DoubleLimitView";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/DoubleLimitView.cs	(revision 15281)
@@ -0,0 +1,41 @@
+﻿#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.Windows.Forms;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("DoubleLimit View")]
+  [Content(typeof(DoubleLimit), true)]
+  public partial class DoubleLimitView : StringConvertibleValueTupleView {
+
+    public new DoubleLimit Content {
+      get { return (DoubleLimit)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DoubleLimitView() {
+      InitializeComponent();
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.Designer.cs	(revision 15281)
@@ -0,0 +1,159 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class FactorPartialDependencePlot {
+    /// <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.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine1 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine2 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      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.Series series2 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Series series3 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Series series4 = new System.Windows.Forms.DataVisualization.Charting.Series();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.calculationPendingLabel = new System.Windows.Forms.Label();
+      this.calculationPendingTimer = new System.Windows.Forms.Timer(this.components);
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // calculationPendingLabel
+      // 
+      this.calculationPendingLabel.BackColor = System.Drawing.Color.White;
+      this.calculationPendingLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Timer;
+      this.calculationPendingLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.calculationPendingLabel.Location = new System.Drawing.Point(3, 3);
+      this.calculationPendingLabel.Margin = new System.Windows.Forms.Padding(0);
+      this.calculationPendingLabel.Name = "calculationPendingLabel";
+      this.calculationPendingLabel.Size = new System.Drawing.Size(17, 17);
+      this.calculationPendingLabel.TabIndex = 1;
+      this.calculationPendingLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.calculationPendingLabel.Visible = false;
+      // 
+      // calculationPendingTimer
+      // 
+      this.calculationPendingTimer.Tick += new System.EventHandler(this.calculationPendingTimer_Tick);
+      // 
+      // chart
+      // 
+      this.chart.AllowDrop = true;
+      verticalLineAnnotation1.AllowMoving = true;
+      verticalLineAnnotation1.AxisXName = "ChartArea\\rX";
+      verticalLineAnnotation1.ClipToChartArea = "ChartArea";
+      verticalLineAnnotation1.IsInfinitive = true;
+      verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
+      verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      verticalLineAnnotation1.Name = "VerticalLineAnnotation";
+      verticalLineAnnotation1.YAxisName = "ChartArea\\rY";
+      this.chart.Annotations.Add(verticalLineAnnotation1);
+      chartArea1.AxisX.IsMarginVisible = false;
+      stripLine1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      stripLine2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      chartArea1.AxisX.StripLines.Add(stripLine1);
+      chartArea1.AxisX.StripLines.Add(stripLine2);
+      chartArea1.Name = "ChartArea";
+      chartArea1.Position.Auto = false;
+      chartArea1.Position.Height = 90F;
+      chartArea1.Position.Width = 100F;
+      chartArea1.Position.Y = 10F;
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.LegendItemOrder = System.Windows.Forms.DataVisualization.Charting.LegendItemOrder.ReversedSeriesOrder;
+      legend1.LegendStyle = System.Windows.Forms.DataVisualization.Charting.LegendStyle.Row;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      series1.BorderColor = System.Drawing.Color.Red;
+      series1.BorderDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      series1.ChartArea = "ChartArea";
+      series1.IsVisibleInLegend = false;
+      series1.Legend = "Default";
+      series1.Name = "Series1";
+      series1.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
+      series1.YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double;
+      series2.ChartArea = "ChartArea";
+      series2.IsVisibleInLegend = false;
+      series2.Legend = "Default";
+      series2.Name = "Series2";
+      series2.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
+      series3.ChartArea = "ChartArea";
+      series3.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.BoxPlot;
+      series3.Color = System.Drawing.Color.Black;
+      series3.Legend = "Default";
+      series3.Name = "Series3";
+      series3.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
+      series3.YValuesPerPoint = 6;
+      series4.ChartArea = "ChartArea";
+      series4.ChartType = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.BoxPlot;
+      series4.Legend = "Default";
+      series4.Name = "Series4";
+      series4.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String;
+      series4.YValuesPerPoint = 6;
+      this.chart.Series.Add(series1);
+      this.chart.Series.Add(series2);
+      this.chart.Series.Add(series3);
+      this.chart.Series.Add(series4);
+      this.chart.Size = new System.Drawing.Size(453, 308);
+      this.chart.TabIndex = 0;
+      title1.Alignment = System.Drawing.ContentAlignment.TopCenter;
+      title1.DockedToChartArea = "ChartArea";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.IsDockedInsideChartArea = false;
+      title1.Name = "Title";
+      title1.Text = "[Title]";
+      this.chart.Titles.Add(title1);
+      this.chart.SelectionRangeChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CursorEventArgs>(this.chart_SelectionRangeChanged);
+      this.chart.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(this.chart_PostPaint);
+      this.chart.DragDrop += new System.Windows.Forms.DragEventHandler(this.chart_DragDrop);
+      this.chart.DragEnter += new System.Windows.Forms.DragEventHandler(this.chart_DragEnter);
+      this.chart.MouseClick += new System.Windows.Forms.MouseEventHandler(this.chart_MouseClick);
+      this.chart.Resize += new System.EventHandler(this.chart_Resize);
+      // 
+      // FactorPartialDependencePlot
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.calculationPendingLabel);
+      this.Controls.Add(this.chart);
+      this.Name = "FactorPartialDependencePlot";
+      this.Size = new System.Drawing.Size(453, 308);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.Label calculationPendingLabel;
+    private System.Windows.Forms.Timer calculationPendingTimer;
+    private System.Windows.Forms.ToolTip toolTip;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/FactorPartialDependencePlot.cs	(revision 15281)
@@ -0,0 +1,574 @@
+﻿#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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class FactorPartialDependencePlot : UserControl, IPartialDependencePlot {
+    private ModifiableDataset sharedFixedVariables; // used for synchronising variable values between charts
+    private ModifiableDataset internalDataset; // holds the x values for each point drawn
+
+    private CancellationTokenSource cancelCurrentRecalculateSource;
+
+    private readonly List<IRegressionSolution> solutions;
+    private readonly Dictionary<IRegressionSolution, Series> seriesCache;
+    private readonly Dictionary<IRegressionSolution, Series> ciSeriesCache;
+
+    #region Properties
+    public string XAxisTitle {
+      get { return chart.ChartAreas[0].AxisX.Title; }
+      set { chart.ChartAreas[0].AxisX.Title = value; }
+    }
+
+    public string YAxisTitle {
+      get { return chart.ChartAreas[0].AxisY.Title; }
+      set { chart.ChartAreas[0].AxisY.Title = value; }
+    }
+
+    public bool ShowLegend {
+      get { return chart.Legends[0].Enabled; }
+      set { chart.Legends[0].Enabled = value; }
+    }
+    public bool ShowCursor {
+      get { return chart.Annotations[0].Visible; }
+      set {
+        chart.Annotations[0].Visible = value;
+        if (!value) chart.Titles[0].Text = string.Empty;
+      }
+    }
+
+    private int yAxisTicks = 5;
+    public int YAxisTicks {
+      get { return yAxisTicks; }
+      set {
+        if (value != yAxisTicks) {
+          yAxisTicks = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+          RecalculateInternalDataset();
+        }
+      }
+    }
+    private double? fixedYAxisMin;
+    public double? FixedYAxisMin {
+      get { return fixedYAxisMin; }
+      set {
+        if ((value.HasValue && fixedYAxisMin.HasValue && !value.Value.IsAlmost(fixedYAxisMin.Value)) || (value.HasValue != fixedYAxisMin.HasValue)) {
+          fixedYAxisMin = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+        }
+      }
+    }
+    private double? fixedYAxisMax;
+    public double? FixedYAxisMax {
+      get { return fixedYAxisMax; }
+      set {
+        if ((value.HasValue && fixedYAxisMax.HasValue && !value.Value.IsAlmost(fixedYAxisMax.Value)) || (value.HasValue != fixedYAxisMax.HasValue)) {
+          fixedYAxisMax = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+        }
+      }
+    }
+
+    private string freeVariable;
+    public string FreeVariable {
+      get { return freeVariable; }
+      set {
+        if (value == freeVariable) return;
+        if (solutions.Any(s => !s.ProblemData.Dataset.StringVariables.Contains(value))) {
+          throw new ArgumentException("Variable does not exist in the ProblemData of the Solutions.");
+        }
+        freeVariable = value;
+        RecalculateInternalDataset();
+      }
+    }
+
+    private double yMin;
+    public double YMin {
+      get { return yMin; }
+    }
+    private double yMax;
+    public double YMax {
+      get { return yMax; }
+    }
+
+    public bool IsZoomed {
+      get { return chart.ChartAreas[0].AxisX.ScaleView.IsZoomed; }
+    }
+
+    internal ElementPosition InnerPlotPosition {
+      get { return chart.ChartAreas[0].InnerPlotPosition; }
+    }
+    #endregion
+
+    private List<string> variableValues;
+
+    public event EventHandler ChartPostPaint;
+
+    public FactorPartialDependencePlot() {
+      InitializeComponent();
+
+      solutions = new List<IRegressionSolution>();
+      seriesCache = new Dictionary<IRegressionSolution, Series>();
+      ciSeriesCache = new Dictionary<IRegressionSolution, Series>();
+
+      // Configure axis
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].CursorX.Interval = 0;
+
+      chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].CursorY.Interval = 0;
+
+      Disposed += Control_Disposed;
+    }
+
+    private void Control_Disposed(object sender, EventArgs e) {
+      if (cancelCurrentRecalculateSource != null)
+        cancelCurrentRecalculateSource.Cancel();
+    }
+
+    public void Configure(IEnumerable<IRegressionSolution> solutions, ModifiableDataset sharedFixedVariables, string freeVariable, IList<string> variableValues, bool initializeAxisRanges = true) {
+      if (!SolutionsCompatible(solutions))
+        throw new ArgumentException("Solutions are not compatible with the problem data.");
+      this.freeVariable = freeVariable;
+      this.variableValues = new List<string>(variableValues);
+
+      this.solutions.Clear();
+      this.solutions.AddRange(solutions);
+
+      // add an event such that whenever a value is changed in the shared dataset, 
+      // this change is reflected in the internal dataset (where the value becomes a whole column)
+      if (this.sharedFixedVariables != null)
+        this.sharedFixedVariables.ItemChanged -= sharedFixedVariables_ItemChanged;
+      this.sharedFixedVariables = sharedFixedVariables;
+      this.sharedFixedVariables.ItemChanged += sharedFixedVariables_ItemChanged;
+
+      RecalculateInternalDataset();
+
+      chart.Series.Clear();
+      seriesCache.Clear();
+      ciSeriesCache.Clear();
+      foreach (var solution in this.solutions) {
+        var series = CreateSeries(solution);
+        seriesCache.Add(solution, series.Item1);
+        if (series.Item2 != null)
+          ciSeriesCache.Add(solution, series.Item2);
+      }
+
+      InitSeriesData();
+      OrderAndColorSeries();
+
+    }
+
+    public async Task RecalculateAsync(bool updateOnFinish = true, bool resetYAxis = true) {
+      if (IsDisposed
+        || sharedFixedVariables == null || !solutions.Any() || string.IsNullOrEmpty(freeVariable)
+        || !variableValues.Any())
+        return;
+
+      calculationPendingTimer.Start();
+
+      // cancel previous recalculate call
+      if (cancelCurrentRecalculateSource != null)
+        cancelCurrentRecalculateSource.Cancel();
+      cancelCurrentRecalculateSource = new CancellationTokenSource();
+      var cancellationToken = cancelCurrentRecalculateSource.Token;
+
+      // Update series
+      try {
+        var limits = await UpdateAllSeriesDataAsync(cancellationToken);
+        chart.Invalidate();
+
+        yMin = limits.Lower;
+        yMax = limits.Upper;
+        // Set y-axis
+        if (resetYAxis)
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+
+        calculationPendingTimer.Stop();
+        calculationPendingLabel.Visible = false;
+        if (updateOnFinish)
+          Update();
+      }
+      catch (OperationCanceledException) { }
+      catch (AggregateException ae) {
+        if (!ae.InnerExceptions.Any(e => e is OperationCanceledException))
+          throw;
+      }
+    }
+
+    public void UpdateTitlePosition() {
+      var title = chart.Titles[0];
+      var plotArea = InnerPlotPosition;
+
+      title.Visible = plotArea.Width != 0;
+
+      title.Position.X = plotArea.X + (plotArea.Width / 2);
+    }
+
+    private static void SetupAxis(EnhancedChart chart, Axis axis, double minValue, double maxValue, int ticks, double? fixedAxisMin, double? fixedAxisMax) {
+      //guard if only one distinct value is present
+      if (minValue.IsAlmost(maxValue)) {
+        minValue = minValue - 0.5;
+        maxValue = minValue + 0.5;
+      }
+
+      double axisMin, axisMax, axisInterval;
+      ChartUtil.CalculateAxisInterval(minValue, maxValue, ticks, out axisMin, out axisMax, out axisInterval);
+      axis.Minimum = fixedAxisMin ?? axisMin;
+      axis.Maximum = fixedAxisMax ?? axisMax;
+      axis.Interval = (axis.Maximum - axis.Minimum) / ticks;
+
+      chart.ChartAreas[0].RecalculateAxesScale();
+    }
+
+
+    private void RecalculateInternalDataset() {
+      if (sharedFixedVariables == null)
+        return;
+
+      var factorValues = new List<string>(variableValues);
+
+      var variables = sharedFixedVariables.VariableNames.ToList();
+      var values = new List<IList>();
+      foreach (var varName in variables) {
+        if (varName == FreeVariable) {
+          values.Add(factorValues);
+        } else if (sharedFixedVariables.VariableHasType<double>(varName)) {
+          values.Add(Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(varName, 0), factorValues.Count).ToList());
+        } else if (sharedFixedVariables.VariableHasType<string>(varName)) {
+          values.Add(Enumerable.Repeat(sharedFixedVariables.GetStringValue(varName, 0), factorValues.Count).ToList());
+        }
+      }
+
+      internalDataset = new ModifiableDataset(variables, values);
+    }
+
+    private Tuple<Series, Series> CreateSeries(IRegressionSolution solution) {
+      var series = new Series {
+        ChartType = SeriesChartType.Column,
+        Name = solution.ProblemData.TargetVariable + " " + solutions.IndexOf(solution),
+        XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String
+      };
+      series.LegendText = series.Name;
+
+      Series confidenceIntervalSeries = null;
+      confidenceIntervalSeries = new Series {
+        ChartType = SeriesChartType.BoxPlot,
+        XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.String,
+        Color = Color.Black,
+        YValuesPerPoint = 5,
+        Name = "95% Conf. Interval " + series.Name,
+        IsVisibleInLegend = false
+      };
+      return Tuple.Create(series, confidenceIntervalSeries);
+    }
+
+    private void OrderAndColorSeries() {
+      chart.SuspendRepaint();
+
+      chart.Series.Clear();
+      // Add mean series for applying palette colors
+      foreach (var solution in solutions) {
+        chart.Series.Add(seriesCache[solution]);
+      }
+
+      chart.Palette = ChartColorPalette.BrightPastel;
+      chart.ApplyPaletteColors();
+      chart.Palette = ChartColorPalette.None;
+
+      // Add confidence interval series after its coresponding series for correct z index
+      foreach (var solution in solutions) {
+        Series ciSeries;
+        if (ciSeriesCache.TryGetValue(solution, out ciSeries)) {
+          int idx = chart.Series.IndexOf(seriesCache[solution]);
+          chart.Series.Insert(idx + 1, ciSeries);
+        }
+      }
+
+      chart.ResumeRepaint(true);
+    }
+
+    private async Task<DoubleLimit> UpdateAllSeriesDataAsync(CancellationToken cancellationToken) {
+      var updateTasks = solutions.Select(solution => UpdateSeriesDataAsync(solution, cancellationToken));
+
+      double min = double.MaxValue, max = double.MinValue;
+      foreach (var update in updateTasks) {
+        var limit = await update;
+        if (limit.Lower < min) min = limit.Lower;
+        if (limit.Upper > max) max = limit.Upper;
+      }
+
+      return new DoubleLimit(min, max);
+    }
+
+    private Task<DoubleLimit> UpdateSeriesDataAsync(IRegressionSolution solution, CancellationToken cancellationToken) {
+      return Task.Run(() => {
+        var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+
+        double min = double.MaxValue, max = double.MinValue;
+
+        var series = seriesCache[solution];
+        for (int i = 0; i < variableValues.Count; i++) {
+          series.Points[i].SetValueXY(variableValues[i], yvalues[i]);
+          if (yvalues[i] < min) min = yvalues[i];
+          if (yvalues[i] > max) max = yvalues[i];
+        }
+
+        cancellationToken.ThrowIfCancellationRequested();
+
+        var confidenceBoundSolution = solution as IConfidenceRegressionSolution;
+        if (confidenceBoundSolution != null) {
+          var confidenceIntervalSeries = ciSeriesCache[solution];
+          var variances = confidenceBoundSolution.Model.GetEstimatedVariances(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+          for (int i = 0; i < variableValues.Count; i++) {
+            var lower = yvalues[i] - 1.96 * Math.Sqrt(variances[i]);
+            var upper = yvalues[i] + 1.96 * Math.Sqrt(variances[i]);
+            confidenceIntervalSeries.Points[i].SetValueXY(variableValues[i], lower, upper, yvalues[i], yvalues[i], yvalues[i]);
+            if (lower < min) min = lower;
+            if (upper > max) max = upper;
+          }
+        }
+
+        cancellationToken.ThrowIfCancellationRequested();
+        return new DoubleLimit(min, max);
+      }, cancellationToken);
+    }
+
+    private void InitSeriesData() {
+      if (internalDataset == null)
+        return;
+
+      foreach (var solution in solutions)
+        InitSeriesData(solution, variableValues);
+    }
+
+    private void InitSeriesData(IRegressionSolution solution, IList<string> values) {
+
+      var series = seriesCache[solution];
+      series.Points.SuspendUpdates();
+      series.Points.Clear();
+      for (int i = 0; i < values.Count; i++) {
+        series.Points.AddXY(values[i], 0.0);
+        series.Points.Last().ToolTip = values[i];
+      }
+
+      UpdateAllSeriesStyles(variableValues.IndexOf(sharedFixedVariables.GetStringValue(FreeVariable, 0)));
+      series.Points.ResumeUpdates();
+
+      Series confidenceIntervalSeries;
+      if (ciSeriesCache.TryGetValue(solution, out confidenceIntervalSeries)) {
+        confidenceIntervalSeries.Points.SuspendUpdates();
+        confidenceIntervalSeries.Points.Clear();
+        for (int i = 0; i < values.Count; i++)
+          confidenceIntervalSeries.Points.AddXY(values[i], 0.0, 0.0, 0.0, 0.0, 0.0);
+        confidenceIntervalSeries.Points.ResumeUpdates();
+      }
+    }
+
+    public async Task AddSolutionAsync(IRegressionSolution solution) {
+      if (!SolutionsCompatible(solutions.Concat(new[] { solution })))
+        throw new ArgumentException("The solution is not compatible with the problem data.");
+      if (solutions.Contains(solution))
+        return;
+
+      solutions.Add(solution);
+
+      var series = CreateSeries(solution);
+      seriesCache.Add(solution, series.Item1);
+      if (series.Item2 != null)
+        ciSeriesCache.Add(solution, series.Item2);
+
+      InitSeriesData(solution, variableValues);
+      OrderAndColorSeries();
+
+      await RecalculateAsync();
+      var args = new EventArgs<IRegressionSolution>(solution);
+      OnSolutionAdded(this, args);
+    }
+
+    public async Task RemoveSolutionAsync(IRegressionSolution solution) {
+      if (!solutions.Remove(solution))
+        return;
+
+      seriesCache.Remove(solution);
+      ciSeriesCache.Remove(solution);
+
+      await RecalculateAsync();
+      var args = new EventArgs<IRegressionSolution>(solution);
+      OnSolutionRemoved(this, args);
+    }
+
+    private static bool SolutionsCompatible(IEnumerable<IRegressionSolution> solutions) {
+      var refSolution = solutions.First();
+      var refSolVars = refSolution.ProblemData.Dataset.VariableNames;
+      foreach (var solution in solutions.Skip(1)) {
+        var variables1 = solution.ProblemData.Dataset.VariableNames;
+        if (!variables1.All(refSolVars.Contains))
+          return false;
+
+        foreach (var factorVar in variables1.Where(solution.ProblemData.Dataset.VariableHasType<string>)) {
+          var distinctVals = refSolution.ProblemData.Dataset.GetStringValues(factorVar).Distinct();
+          if (solution.ProblemData.Dataset.GetStringValues(factorVar).Any(val => !distinctVals.Contains(val))) return false;
+        }
+      }
+      return true;
+    }
+
+    #region Events
+    public event EventHandler<EventArgs<IRegressionSolution>> SolutionAdded;
+    public void OnSolutionAdded(object sender, EventArgs<IRegressionSolution> args) {
+      var added = SolutionAdded;
+      if (added == null) return;
+      added(sender, args);
+    }
+
+    public event EventHandler<EventArgs<IRegressionSolution>> SolutionRemoved;
+    public void OnSolutionRemoved(object sender, EventArgs<IRegressionSolution> args) {
+      var removed = SolutionRemoved;
+      if (removed == null) return;
+      removed(sender, args);
+    }
+
+    public event EventHandler VariableValueChanged;
+    public void OnVariableValueChanged(object sender, EventArgs args) {
+      var changed = VariableValueChanged;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+
+    public event EventHandler ZoomChanged;
+    public void OnZoomChanged(object sender, EventArgs args) {
+      var changed = ZoomChanged;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+
+    private void sharedFixedVariables_ItemChanged(object o, EventArgs<int, int> e) {
+      if (o != sharedFixedVariables) return;
+      var variables = sharedFixedVariables.VariableNames.ToList();
+      var rowIndex = e.Value;
+      var columnIndex = e.Value2;
+
+      var variableName = variables[columnIndex];
+      if (variableName == FreeVariable) return;
+      if (internalDataset.VariableHasType<double>(variableName)) {
+        var v = sharedFixedVariables.GetDoubleValue(variableName, rowIndex);
+        var values = new List<double>(Enumerable.Repeat(v, internalDataset.Rows));
+        internalDataset.ReplaceVariable(variableName, values);
+      } else if (internalDataset.VariableHasType<string>(variableName)) {
+        var v = sharedFixedVariables.GetStringValue(variableName, rowIndex);
+        var values = new List<String>(Enumerable.Repeat(v, internalDataset.Rows));
+        internalDataset.ReplaceVariable(variableName, values);
+      } else {
+        // unsupported type 
+        throw new NotSupportedException();
+      }
+    }
+
+    private async void chart_DragDrop(object sender, DragEventArgs e) {
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (data != null) {
+        var solution = data as IRegressionSolution;
+        if (!solutions.Contains(solution))
+          await AddSolutionAsync(solution);
+      }
+    }
+    private void chart_DragEnter(object sender, DragEventArgs e) {
+      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) return;
+      e.Effect = DragDropEffects.None;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      var regressionSolution = data as IRegressionSolution;
+      if (regressionSolution != null) {
+        e.Effect = DragDropEffects.Copy;
+      }
+    }
+
+    private void calculationPendingTimer_Tick(object sender, EventArgs e) {
+      calculationPendingLabel.Visible = true;
+      Update();
+    }
+
+    private void chart_SelectionRangeChanged(object sender, CursorEventArgs e) {
+      OnZoomChanged(this, EventArgs.Empty);
+    }
+
+    private void chart_Resize(object sender, EventArgs e) {
+      UpdateTitlePosition();
+    }
+
+    private void chart_PostPaint(object sender, ChartPaintEventArgs e) {
+      if (ChartPostPaint != null)
+        ChartPostPaint(this, EventArgs.Empty);
+    }
+    #endregion
+
+    private void chart_MouseClick(object sender, MouseEventArgs e) {
+      var hitTestResult = chart.HitTest(e.X, e.Y, ChartElementType.DataPoint);
+      if (hitTestResult != null && hitTestResult.ChartElementType == ChartElementType.DataPoint) {
+        var series = hitTestResult.Series;
+        var dataPoint = (DataPoint)hitTestResult.Object;
+        var idx = series.Points.IndexOf(dataPoint);
+        UpdateSelectedValue(variableValues[idx]);
+
+        UpdateAllSeriesStyles(idx);
+      }
+    }
+
+    private void UpdateAllSeriesStyles(int selectedValueIndex) {
+      if (ShowCursor) {
+        chart.Titles[0].Text = FreeVariable + " : " + variableValues[selectedValueIndex];
+        chart.Update();
+      }
+      foreach (var s in seriesCache.Values) {
+        if (s.ChartType == SeriesChartType.Column)
+          for (int i = 0; i < s.Points.Count; i++) {
+            if (i != selectedValueIndex) {
+              s.Points[i].BorderDashStyle = ChartDashStyle.NotSet;
+            } else {
+              s.Points[i].BorderDashStyle = ChartDashStyle.Dash;
+              s.Points[i].BorderColor = Color.Red;
+            }
+          }
+      }
+    }
+
+    private void UpdateSelectedValue(string variableValue) {
+      sharedFixedVariables.SetVariableValue(variableValue, FreeVariable, 0);
+      OnVariableValueChanged(this, EventArgs.Empty);
+    }
+  }
+}
+
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.Designer.cs	(revision 15281)
@@ -0,0 +1,144 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class PartialDependencePlot {
+    /// <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.VerticalLineAnnotation verticalLineAnnotation1 = new System.Windows.Forms.DataVisualization.Charting.VerticalLineAnnotation();
+      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine1 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      System.Windows.Forms.DataVisualization.Charting.StripLine stripLine2 = new System.Windows.Forms.DataVisualization.Charting.StripLine();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      System.Windows.Forms.DataVisualization.Charting.Title title1 = new System.Windows.Forms.DataVisualization.Charting.Title();
+      this.calculationPendingLabel = new System.Windows.Forms.Label();
+      this.calculationPendingTimer = new System.Windows.Forms.Timer(this.components);
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.configurationButton = new System.Windows.Forms.Button();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // calculationPendingLabel
+      // 
+      this.calculationPendingLabel.BackColor = System.Drawing.Color.White;
+      this.calculationPendingLabel.Image = HeuristicLab.Common.Resources.VSImageLibrary.Timer;
+      this.calculationPendingLabel.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
+      this.calculationPendingLabel.Location = new System.Drawing.Point(3, 3);
+      this.calculationPendingLabel.Margin = new System.Windows.Forms.Padding(0);
+      this.calculationPendingLabel.Name = "calculationPendingLabel";
+      this.calculationPendingLabel.Size = new System.Drawing.Size(17, 17);
+      this.calculationPendingLabel.TabIndex = 1;
+      this.calculationPendingLabel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.calculationPendingLabel.Visible = false;
+      // 
+      // calculationPendingTimer
+      // 
+      this.calculationPendingTimer.Tick += new System.EventHandler(this.calculationPendingTimer_Tick);
+      // 
+      // chart
+      // 
+      this.chart.AllowDrop = true;
+      verticalLineAnnotation1.AllowMoving = true;
+      verticalLineAnnotation1.AxisXName = "ChartArea\\rX";
+      verticalLineAnnotation1.ClipToChartArea = "ChartArea";
+      verticalLineAnnotation1.IsInfinitive = true;
+      verticalLineAnnotation1.LineColor = System.Drawing.Color.Red;
+      verticalLineAnnotation1.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+      verticalLineAnnotation1.Name = "VerticalLineAnnotation";
+      verticalLineAnnotation1.YAxisName = "ChartArea\\rY";
+      this.chart.Annotations.Add(verticalLineAnnotation1);
+      stripLine1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      stripLine2.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(40)))), ((int)(((byte)(223)))), ((int)(((byte)(58)))), ((int)(((byte)(2)))));
+      chartArea1.AxisX.StripLines.Add(stripLine1);
+      chartArea1.AxisX.StripLines.Add(stripLine2);
+      chartArea1.Name = "ChartArea";
+      chartArea1.Position.Auto = false;
+      chartArea1.Position.Height = 90F;
+      chartArea1.Position.Width = 100F;
+      chartArea1.Position.Y = 10F;
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.LegendItemOrder = System.Windows.Forms.DataVisualization.Charting.LegendItemOrder.ReversedSeriesOrder;
+      legend1.LegendStyle = System.Windows.Forms.DataVisualization.Charting.LegendStyle.Row;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(453, 308);
+      this.chart.TabIndex = 0;
+      title1.Alignment = System.Drawing.ContentAlignment.TopCenter;
+      title1.DockedToChartArea = "ChartArea";
+      title1.Font = new System.Drawing.Font("Microsoft Sans Serif", 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+      title1.IsDockedInsideChartArea = false;
+      title1.Name = "Title";
+      title1.Text = "[Title]";
+      this.chart.Titles.Add(title1);
+      this.chart.SelectionRangeChanged += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CursorEventArgs>(this.chart_SelectionRangeChanged);
+      this.chart.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(this.chart_PostPaint);
+      this.chart.AnnotationPositionChanged += new System.EventHandler(this.chart_AnnotationPositionChanged);
+      this.chart.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
+      this.chart.DragDrop += new System.Windows.Forms.DragEventHandler(this.chart_DragDrop);
+      this.chart.DragEnter += new System.Windows.Forms.DragEventHandler(this.chart_DragEnter);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.Resize += new System.EventHandler(this.chart_Resize);
+      // 
+      // configurationButton
+      // 
+      this.configurationButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.configurationButton.AutoSize = true;
+      this.configurationButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
+      this.configurationButton.Location = new System.Drawing.Point(426, 3);
+      this.configurationButton.Name = "configurationButton";
+      this.configurationButton.Size = new System.Drawing.Size(24, 24);
+      this.configurationButton.TabIndex = 2;
+      this.configurationButton.TabStop = false;
+      this.toolTip.SetToolTip(this.configurationButton, "Configuration");
+      this.configurationButton.UseVisualStyleBackColor = true;
+      this.configurationButton.Click += new System.EventHandler(this.config_Click);
+      // 
+      // PartialDependencePlot
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.configurationButton);
+      this.Controls.Add(this.calculationPendingLabel);
+      this.Controls.Add(this.chart);
+      this.Name = "PartialDependencePlot";
+      this.Size = new System.Drawing.Size(453, 308);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.Label calculationPendingLabel;
+    private System.Windows.Forms.Timer calculationPendingTimer;
+    private System.Windows.Forms.Button configurationButton;
+    private System.Windows.Forms.ToolTip toolTip;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlot.cs	(revision 15281)
@@ -0,0 +1,721 @@
+﻿#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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Globalization;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class PartialDependencePlot : UserControl, IPartialDependencePlot {
+    private ModifiableDataset sharedFixedVariables; // used for syncronising variable values between charts
+    private ModifiableDataset internalDataset; // holds the x values for each point drawn
+
+    private CancellationTokenSource cancelCurrentRecalculateSource;
+
+    private readonly List<IRegressionSolution> solutions;
+    private readonly Dictionary<IRegressionSolution, Series> seriesCache;
+    private readonly Dictionary<IRegressionSolution, Series> ciSeriesCache;
+
+    private readonly ToolStripMenuItem configToolStripMenuItem;
+    private readonly PartialDependencePlotConfigurationDialog configurationDialog;
+
+    #region Properties
+    public string XAxisTitle {
+      get { return chart.ChartAreas[0].AxisX.Title; }
+      set { chart.ChartAreas[0].AxisX.Title = value; }
+    }
+
+    public string YAxisTitle {
+      get { return chart.ChartAreas[0].AxisY.Title; }
+      set { chart.ChartAreas[0].AxisY.Title = value; }
+    }
+
+    public bool ShowLegend {
+      get { return chart.Legends[0].Enabled; }
+      set { chart.Legends[0].Enabled = value; }
+    }
+    public bool ShowCursor {
+      get { return chart.Annotations[0].Visible; }
+      set {
+        chart.Annotations[0].Visible = value;
+        if (!value) chart.Titles[0].Text = string.Empty;
+      }
+    }
+
+    public bool ShowConfigButton {
+      get { return configurationButton.Visible; }
+      set { configurationButton.Visible = value; }
+    }
+
+    private int xAxisTicks = 5;
+    public int XAxisTicks {
+      get { return xAxisTicks; }
+      set {
+        if (value != xAxisTicks) {
+          xAxisTicks = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisX, trainingMin, trainingMax, XAxisTicks, FixedXAxisMin, FixedXAxisMax);
+          RecalculateInternalDataset();
+        }
+      }
+    }
+    private double? fixedXAxisMin;
+    public double? FixedXAxisMin {
+      get { return fixedXAxisMin; }
+      set {
+        if ((value.HasValue && fixedXAxisMin.HasValue && !value.Value.IsAlmost(fixedXAxisMin.Value)) || (value.HasValue != fixedXAxisMin.HasValue)) {
+          fixedXAxisMin = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisX, trainingMin, trainingMax, XAxisTicks, FixedXAxisMin, FixedXAxisMax);
+          RecalculateInternalDataset();
+          // set the vertical line position 
+          if (VerticalLineAnnotation.X <= fixedXAxisMin) {
+            var axisX = chart.ChartAreas[0].AxisX;
+            var step = (axisX.Maximum - axisX.Minimum) / drawingSteps;
+            VerticalLineAnnotation.X = axisX.Minimum + step;
+          }
+        }
+      }
+    }
+    private double? fixedXAxisMax;
+    public double? FixedXAxisMax {
+      get { return fixedXAxisMax; }
+      set {
+        if ((value.HasValue && fixedXAxisMax.HasValue && !value.Value.IsAlmost(fixedXAxisMax.Value)) || (value.HasValue != fixedXAxisMax.HasValue)) {
+          fixedXAxisMax = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisX, trainingMin, trainingMax, XAxisTicks, FixedXAxisMin, FixedXAxisMax);
+          RecalculateInternalDataset();
+          // set the vertical line position 
+          if (VerticalLineAnnotation.X >= fixedXAxisMax) {
+            var axisX = chart.ChartAreas[0].AxisX;
+            var step = (axisX.Maximum - axisX.Minimum) / drawingSteps;
+            VerticalLineAnnotation.X = axisX.Maximum - step;
+          }
+        }
+      }
+    }
+
+    private int yAxisTicks = 5;
+    public int YAxisTicks {
+      get { return yAxisTicks; }
+      set {
+        if (value != yAxisTicks) {
+          yAxisTicks = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+          RecalculateInternalDataset();
+        }
+      }
+    }
+    private double? fixedYAxisMin;
+    public double? FixedYAxisMin {
+      get { return fixedYAxisMin; }
+      set {
+        if ((value.HasValue && fixedYAxisMin.HasValue && !value.Value.IsAlmost(fixedYAxisMin.Value)) || (value.HasValue != fixedYAxisMin.HasValue)) {
+          fixedYAxisMin = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+        }
+      }
+    }
+    private double? fixedYAxisMax;
+    public double? FixedYAxisMax {
+      get { return fixedYAxisMax; }
+      set {
+        if ((value.HasValue && fixedYAxisMax.HasValue && !value.Value.IsAlmost(fixedYAxisMax.Value)) || (value.HasValue != fixedYAxisMax.HasValue)) {
+          fixedYAxisMax = value;
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+        }
+      }
+    }
+
+    private double trainingMin = -1;
+    private double trainingMax = 1;
+
+    private int drawingSteps = 1000;
+    public int DrawingSteps {
+      get { return drawingSteps; }
+      set {
+        if (value != drawingSteps) {
+          drawingSteps = value;
+          RecalculateInternalDataset();
+          ResizeAllSeriesData();
+        }
+      }
+    }
+
+    private string freeVariable;
+    public string FreeVariable {
+      get { return freeVariable; }
+      set {
+        if (value == freeVariable) return;
+        if (solutions.Any(s => !s.ProblemData.Dataset.DoubleVariables.Contains(value))) {
+          throw new ArgumentException("Variable does not exist in the ProblemData of the Solutions.");
+        }
+        freeVariable = value;
+        RecalculateInternalDataset();
+      }
+    }
+
+    private double yMin;
+    public double YMin {
+      get { return yMin; }
+    }
+    private double yMax;
+    public double YMax {
+      get { return yMax; }
+    }
+
+    public bool IsZoomed {
+      get { return chart.ChartAreas[0].AxisX.ScaleView.IsZoomed; }
+    }
+
+    private VerticalLineAnnotation VerticalLineAnnotation {
+      get { return (VerticalLineAnnotation)chart.Annotations.SingleOrDefault(x => x is VerticalLineAnnotation); }
+    }
+
+    internal ElementPosition InnerPlotPosition {
+      get { return chart.ChartAreas[0].InnerPlotPosition; }
+    }
+    #endregion
+
+    public event EventHandler ChartPostPaint;
+
+    public PartialDependencePlot() {
+      InitializeComponent();
+
+      solutions = new List<IRegressionSolution>();
+      seriesCache = new Dictionary<IRegressionSolution, Series>();
+      ciSeriesCache = new Dictionary<IRegressionSolution, Series>();
+
+      // Configure axis
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].CursorX.Interval = 0;
+
+      chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].CursorY.Interval = 0;
+
+      configToolStripMenuItem = new ToolStripMenuItem("Configuration");
+      configToolStripMenuItem.Click += config_Click;
+      chart.ContextMenuStrip.Items.Add(new ToolStripSeparator());
+      chart.ContextMenuStrip.Items.Add(configToolStripMenuItem);
+      configurationDialog = new PartialDependencePlotConfigurationDialog(this);
+
+      Disposed += Control_Disposed;
+    }
+
+    private void Control_Disposed(object sender, EventArgs e) {
+      if (cancelCurrentRecalculateSource != null)
+        cancelCurrentRecalculateSource.Cancel();
+    }
+
+    public void Configure(IEnumerable<IRegressionSolution> solutions, ModifiableDataset sharedFixedVariables, string freeVariable, int drawingSteps, bool initializeAxisRanges = true) {
+      if (!SolutionsCompatible(solutions))
+        throw new ArgumentException("Solutions are not compatible with the problem data.");
+      this.freeVariable = freeVariable;
+      this.drawingSteps = drawingSteps;
+
+      this.solutions.Clear();
+      this.solutions.AddRange(solutions);
+
+      // add an event such that whenever a value is changed in the shared dataset, 
+      // this change is reflected in the internal dataset (where the value becomes a whole column)
+      if (this.sharedFixedVariables != null)
+        this.sharedFixedVariables.ItemChanged -= sharedFixedVariables_ItemChanged;
+      this.sharedFixedVariables = sharedFixedVariables;
+      this.sharedFixedVariables.ItemChanged += sharedFixedVariables_ItemChanged;
+
+      RecalculateTrainingLimits(initializeAxisRanges);
+      RecalculateInternalDataset();
+
+      chart.Series.Clear();
+      seriesCache.Clear();
+      ciSeriesCache.Clear();
+      foreach (var solution in this.solutions) {
+        var series = CreateSeries(solution);
+        seriesCache.Add(solution, series.Item1);
+        if (series.Item2 != null)
+          ciSeriesCache.Add(solution, series.Item2);
+      }
+
+      // Set cursor and x-axis
+      // Make sure to allow a small offset to be able to distinguish the vertical line annotation from the axis
+      var defaultValue = sharedFixedVariables.GetDoubleValue(freeVariable, 0);
+      var step = (trainingMax - trainingMin) / drawingSteps;
+      var minimum = chart.ChartAreas[0].AxisX.Minimum;
+      var maximum = chart.ChartAreas[0].AxisX.Maximum;
+      if (defaultValue <= minimum)
+        VerticalLineAnnotation.X = minimum + step;
+      else if (defaultValue >= maximum)
+        VerticalLineAnnotation.X = maximum - step;
+      else
+        VerticalLineAnnotation.X = defaultValue;
+
+      if (ShowCursor)
+        chart.Titles[0].Text = FreeVariable + " : " + defaultValue.ToString("G5", CultureInfo.CurrentCulture);
+
+      ResizeAllSeriesData();
+      OrderAndColorSeries();
+    }
+
+    public async Task RecalculateAsync(bool updateOnFinish = true, bool resetYAxis = true) {
+      if (IsDisposed
+        || sharedFixedVariables == null || !solutions.Any() || string.IsNullOrEmpty(freeVariable)
+        || trainingMin > trainingMax || drawingSteps == 0)
+        return;
+
+      calculationPendingTimer.Start();
+
+      // cancel previous recalculate call
+      if (cancelCurrentRecalculateSource != null)
+        cancelCurrentRecalculateSource.Cancel();
+      cancelCurrentRecalculateSource = new CancellationTokenSource();
+      var cancellationToken = cancelCurrentRecalculateSource.Token;
+
+      // Update series
+      try {
+        var limits = await UpdateAllSeriesDataAsync(cancellationToken);
+        chart.Invalidate();
+
+        yMin = limits.Lower;
+        yMax = limits.Upper;
+        // Set y-axis
+        if (resetYAxis)
+          SetupAxis(chart, chart.ChartAreas[0].AxisY, yMin, yMax, YAxisTicks, FixedYAxisMin, FixedYAxisMax);
+
+        UpdateOutOfTrainingRangeStripLines();
+
+        calculationPendingTimer.Stop();
+        calculationPendingLabel.Visible = false;
+        if (updateOnFinish)
+          Update();
+      }
+      catch (OperationCanceledException) { }
+      catch (AggregateException ae) {
+        if (!ae.InnerExceptions.Any(e => e is OperationCanceledException))
+          throw;
+      }
+    }
+
+    public void UpdateTitlePosition() {
+      var title = chart.Titles[0];
+      var plotArea = InnerPlotPosition;
+
+      title.Visible = plotArea.Width != 0;
+
+      title.Position.X = plotArea.X + (plotArea.Width / 2);
+    }
+
+    private static void SetupAxis(EnhancedChart chart, Axis axis, double minValue, double maxValue, int ticks, double? fixedAxisMin, double? fixedAxisMax) {
+      //guard if only one distinct value is present
+      if (minValue.IsAlmost(maxValue)) {
+        minValue = minValue - 0.5;
+        maxValue = minValue + 0.5;
+      }
+
+      double axisMin, axisMax, axisInterval;
+      ChartUtil.CalculateAxisInterval(minValue, maxValue, ticks, out axisMin, out axisMax, out axisInterval);
+      axis.Minimum = fixedAxisMin ?? axisMin;
+      axis.Maximum = fixedAxisMax ?? axisMax;
+      axis.Interval = (axis.Maximum - axis.Minimum) / ticks;
+
+      chart.ChartAreas[0].RecalculateAxesScale();
+    }
+
+    private void RecalculateTrainingLimits(bool initializeAxisRanges) {
+      trainingMin = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Min()).Max();
+      trainingMax = solutions.Select(s => s.ProblemData.Dataset.GetDoubleValues(freeVariable, s.ProblemData.TrainingIndices).Max()).Min();
+
+      if (initializeAxisRanges) {
+        double xmin, xmax, xinterval;
+        //guard if only one distinct value is present
+        if (trainingMin.IsAlmost(trainingMax))
+          ChartUtil.CalculateAxisInterval(trainingMin - 0.5, trainingMax + 0.5, XAxisTicks, out xmin, out xmax, out xinterval);
+        else
+          ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out xmin, out xmax, out xinterval);
+
+        FixedXAxisMin = xmin;
+        FixedXAxisMax = xmax;
+      }
+    }
+
+    private void RecalculateInternalDataset() {
+      if (sharedFixedVariables == null)
+        return;
+
+      // we expand the range in order to get nice tick intervals on the x axis
+      double xmin, xmax, xinterval;
+      //guard if only one distinct value is present
+      if (trainingMin.IsAlmost(trainingMax))
+        ChartUtil.CalculateAxisInterval(trainingMin - 0.5, trainingMin + 0.5, XAxisTicks, out xmin, out xmax, out xinterval);
+      else
+        ChartUtil.CalculateAxisInterval(trainingMin, trainingMax, XAxisTicks, out xmin, out xmax, out xinterval);
+
+      if (FixedXAxisMin.HasValue) xmin = FixedXAxisMin.Value;
+      if (FixedXAxisMax.HasValue) xmax = FixedXAxisMax.Value;
+      double step = (xmax - xmin) / drawingSteps;
+
+      var xvalues = new List<double>();
+      for (int i = 0; i < drawingSteps; i++)
+        xvalues.Add(xmin + i * step);
+
+      if (sharedFixedVariables == null)
+        return;
+
+      var variables = sharedFixedVariables.VariableNames.ToList();
+      var values = new List<IList>();
+      foreach (var varName in variables) {
+        if (varName == FreeVariable) {
+          values.Add(xvalues);
+        } else if (sharedFixedVariables.VariableHasType<double>(varName)) {
+          values.Add(Enumerable.Repeat(sharedFixedVariables.GetDoubleValue(varName, 0), xvalues.Count).ToList());
+        } else if (sharedFixedVariables.VariableHasType<string>(varName)) {
+          values.Add(Enumerable.Repeat(sharedFixedVariables.GetStringValue(varName, 0), xvalues.Count).ToList());
+        }
+      }
+
+      internalDataset = new ModifiableDataset(variables, values);
+    }
+
+    private Tuple<Series, Series> CreateSeries(IRegressionSolution solution) {
+      var series = new Series {
+        ChartType = SeriesChartType.Line,
+        Name = solution.ProblemData.TargetVariable + " " + solutions.IndexOf(solution)
+      };
+      series.LegendText = series.Name;
+
+      var confidenceBoundSolution = solution as IConfidenceRegressionSolution;
+      Series confidenceIntervalSeries = null;
+      if (confidenceBoundSolution != null) {
+        confidenceIntervalSeries = new Series {
+          ChartType = SeriesChartType.Range,
+          YValuesPerPoint = 2,
+          Name = "95% Conf. Interval " + series.Name,
+          IsVisibleInLegend = false
+        };
+      }
+      return Tuple.Create(series, confidenceIntervalSeries);
+    }
+
+    private void OrderAndColorSeries() {
+      chart.SuspendRepaint();
+
+      chart.Series.Clear();
+      // Add mean series for applying palette colors
+      foreach (var solution in solutions) {
+        chart.Series.Add(seriesCache[solution]);
+      }
+
+      chart.Palette = ChartColorPalette.BrightPastel;
+      chart.ApplyPaletteColors();
+      chart.Palette = ChartColorPalette.None;
+
+      // Add confidence interval series before its coresponding series for correct z index
+      foreach (var solution in solutions) {
+        Series ciSeries;
+        if (ciSeriesCache.TryGetValue(solution, out ciSeries)) {
+          var series = seriesCache[solution];
+          ciSeries.Color = Color.FromArgb(40, series.Color);
+          int idx = chart.Series.IndexOf(seriesCache[solution]);
+          chart.Series.Insert(idx, ciSeries);
+        }
+      }
+
+      chart.ResumeRepaint(true);
+    }
+
+    private async Task<DoubleLimit> UpdateAllSeriesDataAsync(CancellationToken cancellationToken) {
+      var updateTasks = solutions.Select(solution => UpdateSeriesDataAsync(solution, cancellationToken));
+
+      double min = double.MaxValue, max = double.MinValue;
+      foreach (var update in updateTasks) {
+        var limit = await update;
+        if (limit.Lower < min) min = limit.Lower;
+        if (limit.Upper > max) max = limit.Upper;
+      }
+
+      return new DoubleLimit(min, max);
+    }
+
+    private Task<DoubleLimit> UpdateSeriesDataAsync(IRegressionSolution solution, CancellationToken cancellationToken) {
+      return Task.Run(() => {
+        var xvalues = internalDataset.GetDoubleValues(FreeVariable).ToList();
+        var yvalues = solution.Model.GetEstimatedValues(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+
+        double min = double.MaxValue, max = double.MinValue;
+
+        var series = seriesCache[solution];
+        for (int i = 0; i < xvalues.Count; i++) {
+          series.Points[i].SetValueXY(xvalues[i], yvalues[i]);
+          if (yvalues[i] < min) min = yvalues[i];
+          if (yvalues[i] > max) max = yvalues[i];
+        }
+
+        cancellationToken.ThrowIfCancellationRequested();
+
+        var confidenceBoundSolution = solution as IConfidenceRegressionSolution;
+        if (confidenceBoundSolution != null) {
+          var confidenceIntervalSeries = ciSeriesCache[solution];
+          var variances = confidenceBoundSolution.Model.GetEstimatedVariances(internalDataset, Enumerable.Range(0, internalDataset.Rows)).ToList();
+          for (int i = 0; i < xvalues.Count; i++) {
+            var lower = yvalues[i] - 1.96 * Math.Sqrt(variances[i]);
+            var upper = yvalues[i] + 1.96 * Math.Sqrt(variances[i]);
+            confidenceIntervalSeries.Points[i].SetValueXY(xvalues[i], lower, upper);
+            if (lower < min) min = lower;
+            if (upper > max) max = upper;
+          }
+        }
+
+        cancellationToken.ThrowIfCancellationRequested();
+        return new DoubleLimit(min, max);
+      }, cancellationToken);
+    }
+
+    private void ResizeAllSeriesData() {
+      if (internalDataset == null)
+        return;
+
+      var xvalues = internalDataset.GetDoubleValues(FreeVariable).ToList();
+      foreach (var solution in solutions)
+        ResizeSeriesData(solution, xvalues);
+    }
+    private void ResizeSeriesData(IRegressionSolution solution, IList<double> xvalues = null) {
+      if (xvalues == null)
+        xvalues = internalDataset.GetDoubleValues(FreeVariable).ToList();
+
+      var series = seriesCache[solution];
+      series.Points.SuspendUpdates();
+      series.Points.Clear();
+      for (int i = 0; i < xvalues.Count; i++)
+        series.Points.Add(new DataPoint(xvalues[i], 0.0));
+      series.Points.ResumeUpdates();
+
+      Series confidenceIntervalSeries;
+      if (ciSeriesCache.TryGetValue(solution, out confidenceIntervalSeries)) {
+        confidenceIntervalSeries.Points.SuspendUpdates();
+        confidenceIntervalSeries.Points.Clear();
+        for (int i = 0; i < xvalues.Count; i++)
+          confidenceIntervalSeries.Points.Add(new DataPoint(xvalues[i], new[] { -1.0, 1.0 }));
+        confidenceIntervalSeries.Points.ResumeUpdates();
+      }
+    }
+
+    public async Task AddSolutionAsync(IRegressionSolution solution) {
+      if (!SolutionsCompatible(solutions.Concat(new[] { solution })))
+        throw new ArgumentException("The solution is not compatible with the problem data.");
+      if (solutions.Contains(solution))
+        return;
+
+      solutions.Add(solution);
+      RecalculateTrainingLimits(true);
+
+      var series = CreateSeries(solution);
+      seriesCache.Add(solution, series.Item1);
+      if (series.Item2 != null)
+        ciSeriesCache.Add(solution, series.Item2);
+
+      ResizeSeriesData(solution);
+      OrderAndColorSeries();
+
+      await RecalculateAsync();
+      var args = new EventArgs<IRegressionSolution>(solution);
+      OnSolutionAdded(this, args);
+    }
+
+    public async Task RemoveSolutionAsync(IRegressionSolution solution) {
+      if (!solutions.Remove(solution))
+        return;
+
+      RecalculateTrainingLimits(true);
+
+      seriesCache.Remove(solution);
+      ciSeriesCache.Remove(solution);
+
+      await RecalculateAsync();
+      var args = new EventArgs<IRegressionSolution>(solution);
+      OnSolutionRemoved(this, args);
+    }
+
+    private static bool SolutionsCompatible(IEnumerable<IRegressionSolution> solutions) {
+      var refSolution = solutions.First();
+      var refSolVars = refSolution.ProblemData.Dataset.VariableNames;
+      foreach (var solution in solutions.Skip(1)) {
+        var variables1 = solution.ProblemData.Dataset.VariableNames;
+        if (!variables1.All(refSolVars.Contains))
+          return false;
+
+        foreach (var factorVar in variables1.Where(solution.ProblemData.Dataset.VariableHasType<string>)) {
+          var distinctVals = refSolution.ProblemData.Dataset.GetStringValues(factorVar).Distinct();
+          if (solution.ProblemData.Dataset.GetStringValues(factorVar).Any(val => !distinctVals.Contains(val))) return false;
+        }
+      }
+      return true;
+    }
+
+    private void UpdateOutOfTrainingRangeStripLines() {
+      var axisX = chart.ChartAreas[0].AxisX;
+      var lowerStripLine = axisX.StripLines[0];
+      var upperStripLine = axisX.StripLines[1];
+
+      lowerStripLine.IntervalOffset = axisX.Minimum;
+      lowerStripLine.StripWidth = Math.Abs(trainingMin - axisX.Minimum);
+
+      upperStripLine.IntervalOffset = trainingMax;
+      upperStripLine.StripWidth = Math.Abs(axisX.Maximum - trainingMax);
+    }
+
+    #region Events
+    public event EventHandler<EventArgs<IRegressionSolution>> SolutionAdded;
+    public void OnSolutionAdded(object sender, EventArgs<IRegressionSolution> args) {
+      var added = SolutionAdded;
+      if (added == null) return;
+      added(sender, args);
+    }
+
+    public event EventHandler<EventArgs<IRegressionSolution>> SolutionRemoved;
+    public void OnSolutionRemoved(object sender, EventArgs<IRegressionSolution> args) {
+      var removed = SolutionRemoved;
+      if (removed == null) return;
+      removed(sender, args);
+    }
+
+    public event EventHandler VariableValueChanged;
+    public void OnVariableValueChanged(object sender, EventArgs args) {
+      var changed = VariableValueChanged;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+
+    public event EventHandler ZoomChanged;
+    public void OnZoomChanged(object sender, EventArgs args) {
+      var changed = ZoomChanged;
+      if (changed == null) return;
+      changed(sender, args);
+    }
+
+    private void sharedFixedVariables_ItemChanged(object o, EventArgs<int, int> e) {
+      if (o != sharedFixedVariables) return;
+      var variables = sharedFixedVariables.VariableNames.ToList();
+      var rowIndex = e.Value;
+      var columnIndex = e.Value2;
+
+      var variableName = variables[columnIndex];
+      if (variableName == FreeVariable) return;
+      if (internalDataset.VariableHasType<double>(variableName)) {
+        var v = sharedFixedVariables.GetDoubleValue(variableName, rowIndex);
+        var values = new List<double>(Enumerable.Repeat(v, internalDataset.Rows));
+        internalDataset.ReplaceVariable(variableName, values);
+      } else if (internalDataset.VariableHasType<string>(variableName)) {
+        var v = sharedFixedVariables.GetStringValue(variableName, rowIndex);
+        var values = new List<String>(Enumerable.Repeat(v, internalDataset.Rows));
+        internalDataset.ReplaceVariable(variableName, values);
+      } else {
+        // unsupported type 
+        throw new NotSupportedException();
+      }
+    }
+
+    private void chart_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e) {
+      var step = (trainingMax - trainingMin) / drawingSteps;
+      double newLocation = step * (long)Math.Round(e.NewLocationX / step);
+      var axisX = chart.ChartAreas[0].AxisX;
+      if (newLocation >= axisX.Maximum)
+        newLocation = axisX.Maximum - step;
+      if (newLocation <= axisX.Minimum)
+        newLocation = axisX.Minimum + step;
+
+      e.NewLocationX = newLocation;
+
+      UpdateCursor();
+    }
+    private void chart_AnnotationPositionChanged(object sender, EventArgs e) {
+      UpdateCursor();
+    }
+    private void UpdateCursor() {
+      var x = VerticalLineAnnotation.X;
+      sharedFixedVariables.SetVariableValue(x, FreeVariable, 0);
+
+      if (ShowCursor) {
+        chart.Titles[0].Text = FreeVariable + " : " + x.ToString("G5", CultureInfo.CurrentCulture);
+        chart.Update();
+      }
+
+      OnVariableValueChanged(this, EventArgs.Empty);
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      bool hitCursor = chart.HitTest(e.X, e.Y).ChartElementType == ChartElementType.Annotation;
+      chart.Cursor = hitCursor ? Cursors.VSplit : Cursors.Default;
+    }
+
+    private async void chart_DragDrop(object sender, DragEventArgs e) {
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (data != null) {
+        var solution = data as IRegressionSolution;
+        if (!solutions.Contains(solution))
+          await AddSolutionAsync(solution);
+      }
+    }
+    private void chart_DragEnter(object sender, DragEventArgs e) {
+      if (!e.Data.GetDataPresent(HeuristicLab.Common.Constants.DragDropDataFormat)) return;
+      e.Effect = DragDropEffects.None;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      var regressionSolution = data as IRegressionSolution;
+      if (regressionSolution != null) {
+        e.Effect = DragDropEffects.Copy;
+      }
+    }
+
+    private void calculationPendingTimer_Tick(object sender, EventArgs e) {
+      calculationPendingLabel.Visible = true;
+      Update();
+    }
+
+    private void config_Click(object sender, EventArgs e) {
+      configurationDialog.ShowDialog(this);
+    }
+
+    private void chart_SelectionRangeChanged(object sender, CursorEventArgs e) {
+      OnZoomChanged(this, EventArgs.Empty);
+    }
+
+    private void chart_Resize(object sender, EventArgs e) {
+      UpdateTitlePosition();
+    }
+
+    private void chart_PostPaint(object sender, ChartPaintEventArgs e) {
+      if (ChartPostPaint != null)
+        ChartPostPaint(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
+
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.Designer.cs	(revision 15281)
@@ -0,0 +1,327 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class PartialDependencePlotConfigurationDialog {
+    /// <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();
+      this.xAxisGroupBox = new System.Windows.Forms.GroupBox();
+      this.maxXTextBox = new System.Windows.Forms.TextBox();
+      this.xAutomaticCheckBox = new System.Windows.Forms.CheckBox();
+      this.minXTextBox = new System.Windows.Forms.TextBox();
+      this.maxXLabel = new System.Windows.Forms.Label();
+      this.minXLabel = new System.Windows.Forms.Label();
+      this.yAxisGroupBox = new System.Windows.Forms.GroupBox();
+      this.maxYTextBox = new System.Windows.Forms.TextBox();
+      this.yAutomaticCheckBox = new System.Windows.Forms.CheckBox();
+      this.minYTextBox = new System.Windows.Forms.TextBox();
+      this.maxYLabel = new System.Windows.Forms.Label();
+      this.minYLabel = new System.Windows.Forms.Label();
+      this.miscGroupBox = new System.Windows.Forms.GroupBox();
+      this.StepsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.stepsLabel = new System.Windows.Forms.Label();
+      this.applyButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.xAxisGroupBox.SuspendLayout();
+      this.yAxisGroupBox.SuspendLayout();
+      this.miscGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.StepsNumericUpDown)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // xAxisGroupBox
+      // 
+      this.xAxisGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.xAxisGroupBox.Controls.Add(this.maxXTextBox);
+      this.xAxisGroupBox.Controls.Add(this.xAutomaticCheckBox);
+      this.xAxisGroupBox.Controls.Add(this.minXTextBox);
+      this.xAxisGroupBox.Controls.Add(this.maxXLabel);
+      this.xAxisGroupBox.Controls.Add(this.minXLabel);
+      this.xAxisGroupBox.Location = new System.Drawing.Point(12, 12);
+      this.xAxisGroupBox.Name = "xAxisGroupBox";
+      this.xAxisGroupBox.Size = new System.Drawing.Size(234, 78);
+      this.xAxisGroupBox.TabIndex = 1;
+      this.xAxisGroupBox.TabStop = false;
+      this.xAxisGroupBox.Text = "X-Axis";
+      // 
+      // maxXTextBox
+      // 
+      this.maxXTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.maxXTextBox.Location = new System.Drawing.Point(61, 45);
+      this.maxXTextBox.Name = "maxXTextBox";
+      this.maxXTextBox.Size = new System.Drawing.Size(167, 20);
+      this.maxXTextBox.TabIndex = 3;
+      this.maxXTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.numberTextBox_Validating);
+      this.maxXTextBox.Validated += new System.EventHandler(this.numberTextBox_Validated);
+      // 
+      // xAutomaticCheckBox
+      // 
+      this.xAutomaticCheckBox.AutoSize = true;
+      this.xAutomaticCheckBox.Location = new System.Drawing.Point(48, -1);
+      this.xAutomaticCheckBox.Name = "xAutomaticCheckBox";
+      this.xAutomaticCheckBox.Size = new System.Drawing.Size(73, 17);
+      this.xAutomaticCheckBox.TabIndex = 1;
+      this.xAutomaticCheckBox.Text = "Automatic";
+      this.xAutomaticCheckBox.UseVisualStyleBackColor = true;
+      this.xAutomaticCheckBox.CheckedChanged += new System.EventHandler(this.automaticCheckBox_CheckedChanged);
+      // 
+      // minXTextBox
+      // 
+      this.minXTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.minXTextBox.Location = new System.Drawing.Point(61, 19);
+      this.minXTextBox.Name = "minXTextBox";
+      this.minXTextBox.Size = new System.Drawing.Size(167, 20);
+      this.minXTextBox.TabIndex = 2;
+      this.minXTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.numberTextBox_Validating);
+      this.minXTextBox.Validated += new System.EventHandler(this.numberTextBox_Validated);
+      // 
+      // maxXLabel
+      // 
+      this.maxXLabel.AutoSize = true;
+      this.maxXLabel.Location = new System.Drawing.Point(7, 48);
+      this.maxXLabel.Name = "maxXLabel";
+      this.maxXLabel.Size = new System.Drawing.Size(27, 13);
+      this.maxXLabel.TabIndex = 1;
+      this.maxXLabel.Text = "Max";
+      // 
+      // minXLabel
+      // 
+      this.minXLabel.AutoSize = true;
+      this.minXLabel.Location = new System.Drawing.Point(7, 22);
+      this.minXLabel.Name = "minXLabel";
+      this.minXLabel.Size = new System.Drawing.Size(24, 13);
+      this.minXLabel.TabIndex = 0;
+      this.minXLabel.Text = "Min";
+      // 
+      // yAxisGroupBox
+      // 
+      this.yAxisGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.yAxisGroupBox.Controls.Add(this.maxYTextBox);
+      this.yAxisGroupBox.Controls.Add(this.yAutomaticCheckBox);
+      this.yAxisGroupBox.Controls.Add(this.minYTextBox);
+      this.yAxisGroupBox.Controls.Add(this.maxYLabel);
+      this.yAxisGroupBox.Controls.Add(this.minYLabel);
+      this.yAxisGroupBox.Location = new System.Drawing.Point(13, 96);
+      this.yAxisGroupBox.Name = "yAxisGroupBox";
+      this.yAxisGroupBox.Size = new System.Drawing.Size(234, 75);
+      this.yAxisGroupBox.TabIndex = 2;
+      this.yAxisGroupBox.TabStop = false;
+      this.yAxisGroupBox.Text = "Y-Axis";
+      // 
+      // maxYTextBox
+      // 
+      this.maxYTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.maxYTextBox.Location = new System.Drawing.Point(61, 45);
+      this.maxYTextBox.Name = "maxYTextBox";
+      this.maxYTextBox.Size = new System.Drawing.Size(167, 20);
+      this.maxYTextBox.TabIndex = 3;
+      this.maxYTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.numberTextBox_Validating);
+      this.maxYTextBox.Validated += new System.EventHandler(this.numberTextBox_Validated);
+      // 
+      // yAutomaticCheckBox
+      // 
+      this.yAutomaticCheckBox.AutoSize = true;
+      this.yAutomaticCheckBox.Location = new System.Drawing.Point(47, -1);
+      this.yAutomaticCheckBox.Name = "yAutomaticCheckBox";
+      this.yAutomaticCheckBox.Size = new System.Drawing.Size(73, 17);
+      this.yAutomaticCheckBox.TabIndex = 1;
+      this.yAutomaticCheckBox.Text = "Automatic";
+      this.yAutomaticCheckBox.UseVisualStyleBackColor = true;
+      this.yAutomaticCheckBox.CheckedChanged += new System.EventHandler(this.automaticCheckBox_CheckedChanged);
+      // 
+      // minYTextBox
+      // 
+      this.minYTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.minYTextBox.Location = new System.Drawing.Point(61, 19);
+      this.minYTextBox.Name = "minYTextBox";
+      this.minYTextBox.Size = new System.Drawing.Size(167, 20);
+      this.minYTextBox.TabIndex = 2;
+      this.minYTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.numberTextBox_Validating);
+      this.minYTextBox.Validated += new System.EventHandler(this.numberTextBox_Validated);
+      // 
+      // maxYLabel
+      // 
+      this.maxYLabel.AutoSize = true;
+      this.maxYLabel.Location = new System.Drawing.Point(7, 48);
+      this.maxYLabel.Name = "maxYLabel";
+      this.maxYLabel.Size = new System.Drawing.Size(27, 13);
+      this.maxYLabel.TabIndex = 1;
+      this.maxYLabel.Text = "Max";
+      // 
+      // minYLabel
+      // 
+      this.minYLabel.AutoSize = true;
+      this.minYLabel.Location = new System.Drawing.Point(7, 22);
+      this.minYLabel.Name = "minYLabel";
+      this.minYLabel.Size = new System.Drawing.Size(24, 13);
+      this.minYLabel.TabIndex = 0;
+      this.minYLabel.Text = "Min";
+      // 
+      // miscGroupBox
+      // 
+      this.miscGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.miscGroupBox.Controls.Add(this.StepsNumericUpDown);
+      this.miscGroupBox.Controls.Add(this.stepsLabel);
+      this.miscGroupBox.Location = new System.Drawing.Point(13, 177);
+      this.miscGroupBox.Name = "miscGroupBox";
+      this.miscGroupBox.Size = new System.Drawing.Size(233, 53);
+      this.miscGroupBox.TabIndex = 4;
+      this.miscGroupBox.TabStop = false;
+      // 
+      // StepsNumericUpDown
+      // 
+      this.StepsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.StepsNumericUpDown.Increment = new decimal(new int[] {
+            50,
+            0,
+            0,
+            0});
+      this.StepsNumericUpDown.Location = new System.Drawing.Point(61, 20);
+      this.StepsNumericUpDown.Maximum = new decimal(new int[] {
+            100000,
+            0,
+            0,
+            0});
+      this.StepsNumericUpDown.Name = "StepsNumericUpDown";
+      this.StepsNumericUpDown.Size = new System.Drawing.Size(166, 20);
+      this.StepsNumericUpDown.TabIndex = 4;
+      // 
+      // stepsLabel
+      // 
+      this.stepsLabel.AutoSize = true;
+      this.stepsLabel.Location = new System.Drawing.Point(6, 22);
+      this.stepsLabel.Name = "stepsLabel";
+      this.stepsLabel.Size = new System.Drawing.Size(34, 13);
+      this.stepsLabel.TabIndex = 1;
+      this.stepsLabel.Text = "Steps";
+      // 
+      // applyButton
+      // 
+      this.applyButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.applyButton.Location = new System.Drawing.Point(91, 239);
+      this.applyButton.Name = "applyButton";
+      this.applyButton.Size = new System.Drawing.Size(75, 23);
+      this.applyButton.TabIndex = 5;
+      this.applyButton.Text = "Apply";
+      this.applyButton.UseVisualStyleBackColor = true;
+      this.applyButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(172, 239);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 6;
+      this.cancelButton.Text = "Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // PartialDependencePlotConfigurationDialog
+      // 
+      this.AcceptButton = this.applyButton;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(258, 272);
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.applyButton);
+      this.Controls.Add(this.miscGroupBox);
+      this.Controls.Add(this.xAxisGroupBox);
+      this.Controls.Add(this.yAxisGroupBox);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "PartialDependencePlotConfigurationDialog";
+      this.ShowIcon = false;
+      this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
+      this.Text = "Configure Gradient Chart";
+      this.TopMost = true;
+      this.Shown += new System.EventHandler(this.PartialDependencePlotConfigurationDialog_Shown);
+      this.xAxisGroupBox.ResumeLayout(false);
+      this.xAxisGroupBox.PerformLayout();
+      this.yAxisGroupBox.ResumeLayout(false);
+      this.yAxisGroupBox.PerformLayout();
+      this.miscGroupBox.ResumeLayout(false);
+      this.miscGroupBox.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.StepsNumericUpDown)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox xAxisGroupBox;
+    private System.Windows.Forms.TextBox maxXTextBox;
+    private System.Windows.Forms.TextBox minXTextBox;
+    private System.Windows.Forms.Label maxXLabel;
+    private System.Windows.Forms.Label minXLabel;
+    private System.Windows.Forms.GroupBox yAxisGroupBox;
+    private System.Windows.Forms.TextBox maxYTextBox;
+    private System.Windows.Forms.CheckBox yAutomaticCheckBox;
+    private System.Windows.Forms.TextBox minYTextBox;
+    private System.Windows.Forms.Label maxYLabel;
+    private System.Windows.Forms.Label minYLabel;
+    private System.Windows.Forms.GroupBox miscGroupBox;
+    private System.Windows.Forms.Label stepsLabel;
+    private System.Windows.Forms.Button applyButton;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.CheckBox xAutomaticCheckBox;
+    private System.Windows.Forms.NumericUpDown StepsNumericUpDown;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Controls/PartialDependencePlotConfigurationDialog.cs	(revision 15281)
@@ -0,0 +1,121 @@
+﻿#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.ComponentModel;
+using System.Globalization;
+using System.Windows.Forms;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class PartialDependencePlotConfigurationDialog : Form {
+    private readonly PartialDependencePlot chart;
+
+    public PartialDependencePlotConfigurationDialog(PartialDependencePlot chart) {
+      this.chart = chart;
+      InitializeComponent();
+    }
+
+    private void PartialDependencePlotConfigurationDialog_Shown(object sender, EventArgs e) {
+      if (chart.FixedXAxisMin.HasValue && chart.FixedXAxisMax.HasValue) {
+        xAutomaticCheckBox.Checked = false;
+        minXTextBox.Text = chart.FixedXAxisMin.Value.ToString(CultureInfo.CurrentUICulture);
+        maxXTextBox.Text = chart.FixedXAxisMax.Value.ToString(CultureInfo.CurrentUICulture);
+      } else xAutomaticCheckBox.Checked = true;
+      if (chart.FixedYAxisMin.HasValue && chart.FixedYAxisMax.HasValue) {
+        yAutomaticCheckBox.Checked = false;
+        minYTextBox.Text = chart.FixedYAxisMin.Value.ToString(CultureInfo.CurrentUICulture);
+        maxYTextBox.Text = chart.FixedYAxisMax.Value.ToString(CultureInfo.CurrentUICulture);
+      } else yAutomaticCheckBox.Checked = true;
+      StepsNumericUpDown.Value = chart.DrawingSteps;
+    }
+
+    private async void okButton_Click(object sender, System.EventArgs e) {
+      try {
+        Enabled = false;
+        chart.SuspendRepaint();
+        if (xAutomaticCheckBox.Checked) {
+          chart.FixedXAxisMin = null;
+          chart.FixedXAxisMax = null;
+        } else {
+          var min = double.Parse(minXTextBox.Text, CultureInfo.CurrentUICulture);
+          var max = double.Parse(maxXTextBox.Text, CultureInfo.CurrentUICulture);
+          chart.FixedXAxisMin = min;
+          chart.FixedXAxisMax = max;
+        }
+
+        if (yAutomaticCheckBox.Checked) {
+          chart.FixedYAxisMin = null;
+          chart.FixedYAxisMax = null;
+        } else {
+          var min = double.Parse(minYTextBox.Text, CultureInfo.CurrentUICulture);
+          var max = double.Parse(maxYTextBox.Text, CultureInfo.CurrentUICulture);
+          chart.FixedYAxisMin = min;
+          chart.FixedYAxisMax = max;
+        }
+
+        chart.DrawingSteps = (int)StepsNumericUpDown.Value;
+
+        await chart.RecalculateAsync(resetYAxis: false);
+
+        Close();
+      }
+      catch (FormatException) {
+        MessageBox.Show(this, "Illegal number format", "Wrong format", MessageBoxButtons.OK, MessageBoxIcon.Error);
+      }
+      finally {
+        Enabled = true;
+        chart.ResumeRepaint(true);
+      }
+    }
+
+    private void automaticCheckBox_CheckedChanged(object sender, EventArgs e) {
+      minXTextBox.Enabled = !xAutomaticCheckBox.Checked;
+      maxXTextBox.Enabled = !xAutomaticCheckBox.Checked;
+
+      minYTextBox.Enabled = !yAutomaticCheckBox.Checked;
+      maxYTextBox.Enabled = !yAutomaticCheckBox.Checked;
+    }
+
+    private void numberTextBox_Validating(object sender, CancelEventArgs e) {
+      var textBox = sender as TextBox;
+      if (textBox != null) {
+        double number;
+        if (!double.TryParse(textBox.Text, NumberStyles.Any, CultureInfo.CurrentUICulture, out number)) {
+          e.Cancel = true;
+          applyButton.Enabled = false;
+          errorProvider.SetIconAlignment(textBox, ErrorIconAlignment.MiddleLeft);
+          errorProvider.SetIconPadding(textBox, 2);
+          errorProvider.SetError(textBox, "Illegal number format");
+          textBox.SelectAll();
+        }
+      }
+    }
+
+    private void numberTextBox_Validated(object sender, EventArgs e) {
+      var textBox = sender as TextBox;
+      if (textBox != null) {
+        errorProvider.SetError(textBox, string.Empty);
+        applyButton.Enabled = true;
+      }
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.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.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.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.Problems.DataAnalysis.Views/3.4/DoubleLimitView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.Designer.cs	(revision 15280)
+++ 	(revision )
@@ -1,69 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-namespace HeuristicLab.Problems.DataAnalysis.Views {
-  public partial class DoubleLimitView {
-    /// <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.SuspendLayout();
-      // 
-      // Item1Label
-      // 
-      this.Item1Label.Size = new System.Drawing.Size(39, 13);
-      this.Item1Label.Text = "Lower:";
-      // 
-      // Item2Label
-      // 
-      this.Item2Label.Size = new System.Drawing.Size(39, 13);
-      this.Item2Label.Text = "Upper:";
-      // 
-      // DoubleLimitView
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.Name = "DoubleLimitView";
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-  }
-}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.cs	(revision 15280)
+++ 	(revision )
@@ -1,41 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System.Windows.Forms;
-using HeuristicLab.Data.Views;
-using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
-
-namespace HeuristicLab.Problems.DataAnalysis.Views {
-  [View("DoubleLimit View")]
-  [Content(typeof(DoubleLimit), true)]
-  public partial class DoubleLimitView : StringConvertibleValueTupleView {
-
-    public new DoubleLimit Content {
-      get { return (DoubleLimit)base.Content; }
-      set { base.Content = value; }
-    }
-
-    public DoubleLimitView() {
-      InitializeComponent();
-    }
-  }
-}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs	(revision 15281)
@@ -2,5 +2,5 @@
 
 /* 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.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.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.
@@ -50,5 +50,5 @@
 
       IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
-      OnlineCalculatorError error = OnlineCalculatorError.None;
+
       int length = doubleVariableNames.Count;
       double[,] elements = new double[length, length];
@@ -68,4 +68,5 @@
           var var2 = dataset.GetDoubleValues(doubleVariableNames[j], indices);
 
+          OnlineCalculatorError error = OnlineCalculatorError.None;
           if (bwInfo.IgnoreMissingValues) {
             var filtered = FilterNaNValues(var1, var2);
@@ -78,8 +79,8 @@
           }
           elements[j, i] = elements[i, j];
-
         });
         worker.ReportProgress((int)(((double)counter) / length * 100));
       }
+
       e.Result = elements;
       worker.ReportProgress(100);
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 15281)
@@ -2,5 +2,5 @@
 
 /* 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.
@@ -89,5 +89,5 @@
       this.ignoreMissingValuesCheckbox.Size = new System.Drawing.Size(122, 17);
       this.ignoreMissingValuesCheckbox.TabIndex = 11;
-      this.ignoreMissingValuesCheckbox.Text = "ignoreMissingValues";
+      this.ignoreMissingValuesCheckbox.Text = "Ignore missing values";
       this.ignoreMissingValuesCheckbox.UseVisualStyleBackColor = true;
       this.ignoreMissingValuesCheckbox.CheckedChanged += new System.EventHandler(this.ignoreMissingValuesCheckbox_CheckedChanged);
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs	(revision 15281)
@@ -72,4 +72,6 @@
       }
 
+      var var1 = dataset.GetDoubleValues(variable, indices).ToArray();
+
       for (int i = 0; i < length; i++) {
         for (int j = start; j <= frames; j++) {
@@ -80,14 +82,8 @@
           }
 
-          IEnumerable<double> var1 = dataset.GetDoubleValues(variable, indices);
           IEnumerable<double> var2 = dataset.GetDoubleValues(doubleVariableNames[i], indices);
 
-          var valuesInFrame = var1.Take(j);
-          var help = var1.Skip(j).ToList();
-          help.AddRange(valuesInFrame);
-          var1 = help;
-
           var error = OnlineCalculatorError.None;
-          elements[i, j] = calc.Calculate(var1, var2, out error);
+          elements[i, j] = calc.Calculate(var1.Skip(j), var2.Take(var1.Length-j), out error);
 
           if (!error.Equals(OnlineCalculatorError.None)) {
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs	(revision 15281)
@@ -2,5 +2,5 @@
 
 /* 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.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 15281)
@@ -120,4 +120,34 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Controls\DensityChart.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Controls\DensityChart.Designer.cs">
+      <DependentUpon>DensityChart.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Controls\DensityTrackbar.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Controls\DensityTrackbar.Designer.cs">
+      <DependentUpon>DensityTrackbar.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Controls\FactorPartialDependencePlot.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Controls\FactorPartialDependencePlot.Designer.cs">
+      <DependentUpon>FactorPartialDependencePlot.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Controls\PartialDependencePlot.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Controls\PartialDependencePlot.Designer.cs">
+      <DependentUpon>PartialDependencePlot.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Controls\PartialDependencePlotConfigurationDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Controls\PartialDependencePlotConfigurationDialog.Designer.cs">
+      <DependentUpon>PartialDependencePlotConfigurationDialog.cs</DependentUpon>
+    </Compile>
     <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationCalculator.cs" />
     <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationCalculator.cs" />
@@ -184,4 +214,6 @@
     </Compile>
     <Compile Include="Interfaces\IDataPreprocessorStarter.cs" />
+    <Compile Include="Interfaces\IPartialDependencePlot.cs" />
+    <Compile Include="MenuItems\ChangeDataOfOptimizersMenuItem.cs" />
     <Compile Include="MenuItems\ShrinkDataAnalysisRunsMenuItem.cs" />
     <Compile Include="ModifiableDatasetView.cs">
@@ -198,4 +230,16 @@
       <DependentUpon>ProblemDataView.cs</DependentUpon>
     </Compile>
+    <Compile Include="Regression\ConfidenceRegressionSolutionEstimatedValuesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\ConfidenceRegressionSolutionEstimatedValuesView.Designer.cs">
+      <DependentUpon>ConfidenceRegressionSolutionEstimatedValuesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\ConfidenceRegressionSolutionLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\ConfidenceRegressionSolutionLineChartView.Designer.cs">
+      <DependentUpon>ConfidenceRegressionSolutionLineChartView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Regression\RegressionEnsembleSolutionModelWeightsView.cs">
       <SubType>UserControl</SubType>
@@ -210,4 +254,40 @@
       <DependentUpon>RegressionFeatureCorrelationView.cs</DependentUpon>
     </Compile>
+    <Compile Include="Regression\RegressionSolutionLineChartViewBase.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionLineChartViewBase.Designer.cs">
+      <DependentUpon>RegressionSolutionLineChartViewBase.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionPartialDependencePlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionPartialDependencePlotView.Designer.cs">
+      <DependentUpon>RegressionSolutionPartialDependencePlotView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualsLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualsLineChartView.Designer.cs">
+      <DependentUpon>RegressionSolutionResidualsLineChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualAnalysisView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualAnalysisView.Designer.cs">
+      <DependentUpon>RegressionSolutionResidualAnalysisView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionVariableImpactsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionVariableImpactsView.Designer.cs">
+      <DependentUpon>RegressionSolutionVariableImpactsView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionGradientView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionGradientView.Designer.cs">
+      <DependentUpon>RegressionSolutionGradientView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Regression\RegressionTimeframeFeatureCorrelationView.cs">
       <SubType>UserControl</SubType>
@@ -318,8 +398,8 @@
       <DependentUpon>DataAnalysisSolutionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="DoubleLimitView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="DoubleLimitView.Designer.cs">
+    <Compile Include="Controls\DoubleLimitView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Controls\DoubleLimitView.Designer.cs">
       <DependentUpon>DoubleLimitView.cs</DependentUpon>
     </Compile>
@@ -355,4 +435,16 @@
     <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.Designer.cs">
       <DependentUpon>TimeSeriesPrognosisSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResidualsLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResidualsLineChartView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisResidualsLineChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisLineChartView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisLineChartView.cs</DependentUpon>
     </Compile>
     <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.cs">
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.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.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataPreprocessorStarter.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.Problems.DataAnalysis.Views/3.4/Interfaces/IPartialDependencePlot.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IPartialDependencePlot.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IPartialDependencePlot.cs	(revision 15281)
@@ -0,0 +1,37 @@
+﻿#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.Threading.Tasks;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public interface IPartialDependencePlot {
+    Task RecalculateAsync(bool updateOnFinish, bool resetYAxis);
+    double YMin { get;  }
+    double YMax { get; }
+    double? FixedYAxisMin { get; set; }
+    double? FixedYAxisMax { get; set; }
+    string YAxisTitle { get; set; }
+    Task AddSolutionAsync(IRegressionSolution solution);
+    Task RemoveSolutionAsync(IRegressionSolution solution);
+    bool IsZoomed { get; }
+    void Refresh();
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ChangeDataOfOptimizersMenuItem.cs	(revision 15281)
@@ -0,0 +1,115 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimizer;
+using MenuItem = HeuristicLab.MainForm.WindowsForms.MenuItem;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  internal sealed class ChangeDataOfOptimizersMenuItem : MenuItem, IOptimizerUserInterfaceItemProvider {
+    public override string Name {
+      get { return "Change problem data"; }
+    }
+    public override IEnumerable<string> Structure {
+      get { return new string[] { "&Edit", "&Data Analysis" }; }
+    }
+    public override int Position {
+      get { return 5400; }
+    }
+    public override string ToolTipText {
+      get { return "This command changes the problem data of all optimizers in the active view."; }
+    }
+
+    protected override void OnToolStripItemSet(EventArgs e) {
+      ToolStripItem.Enabled = false;
+    }
+
+    protected override void OnActiveViewChanged(object sender, EventArgs e) {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if (activeView == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      var optimizer = activeView.Content as IOptimizer;
+      if (optimizer == null) {
+        ToolStripItem.Enabled = false;
+        return;
+      }
+
+      ToolStripItem.Enabled = true;
+    }
+
+    public override void Execute() {
+      using (OpenFileDialog openFileDialog = new OpenFileDialog()) {
+        openFileDialog.Title = "Open Problem file";
+        openFileDialog.FileName = "Item";
+        openFileDialog.Multiselect = false;
+        openFileDialog.DefaultExt = "hl";
+        openFileDialog.Filter = "HeuristicLab Files|*.hl|All Files|*.*";
+
+        if (openFileDialog.ShowDialog() != DialogResult.OK) return;
+
+        var content = ContentManager.Load(openFileDialog.FileName);
+        var problem = content as IDataAnalysisProblem;
+        IDataAnalysisProblemData problemData = null;
+        if (problem != null) {
+          problemData = problem.ProblemData;
+        } else {
+          problemData = content as IDataAnalysisProblemData;
+        }
+        if (problemData == null) throw new ArgumentException("The specified file does not contain a HeuristicLab problem.");
+
+        var activeView = (IContentView)MainFormManager.MainForm.ActiveView;
+        var optimizer = (IOptimizer)activeView.Content;
+        var newOptimizer = (IOptimizer)optimizer.Clone();
+
+        var algorithm = newOptimizer as IAlgorithm;
+        if (algorithm != null) {
+          ChangeProblemData(algorithm, problemData);
+        }
+        foreach (var alg in newOptimizer.NestedOptimizers.OfType<IAlgorithm>()) {
+          ChangeProblemData(alg, (IDataAnalysisProblemData)problemData.Clone());
+          if (problem != null) alg.Name += " " + problem.Name;
+        }
+
+        MainFormManager.MainForm.ShowContent(newOptimizer);
+      }
+
+    }
+
+    private void ChangeProblemData(IAlgorithm algorithm, IDataAnalysisProblemData problemData) {
+      if (algorithm == null) throw new ArgumentNullException("algorithm");
+      if (problemData == null) throw new ArgumentNullException("problemData");
+
+      var problem = algorithm.Problem as IDataAnalysisProblem;
+      if (problem != null) problem.ProblemDataParameter.ActualValue = problemData;
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.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.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/ShrinkDataAnalysisRunsMenuItem.cs	(revision 15281)
@@ -2,5 +2,5 @@
 
 /* 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.Problems.DataAnalysis.Views/3.4/ModifiableDatasetView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ModifiableDatasetView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ModifiableDatasetView.cs	(revision 15281)
@@ -2,5 +2,5 @@
 
 /* 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.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/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 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  [Plugin("HeuristicLab.Problems.DataAnalysis.Views", "Provides views for base classes for data analysis tasks.", "3.4.9.$WCREV$")]
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Views", "Provides views for base classes for data analysis tasks.", "3.4.10.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Views-3.4.dll", PluginFileType.Assembly)]
   [PluginDependency("HeuristicLab.ALGLIB", "3.7.0")]
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.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.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.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.Problems.DataAnalysis.Views/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/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.
@@ -31,5 +31,5 @@
 [assembly: AssemblyCompany("")]
 [assembly: AssemblyProduct("HeuristicLab")]
-[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[assembly: AssemblyCopyright("(c) 2002-2016 HEAL")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
@@ -53,3 +53,3 @@
 // by using the '*' as shown below:
 [assembly: AssemblyVersion("3.4.0.0")]
-[assembly: AssemblyFileVersion("3.4.9.$WCREV$")]
+[assembly: AssemblyFileVersion("3.4.10.$WCREV$")]
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.Designer.cs	(revision 15281)
@@ -0,0 +1,62 @@
+﻿#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.Algorithms.DataAnalysis.Views {
+  partial class ConfidenceRegressionSolutionEstimatedValuesView {
+    /// <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.SuspendLayout();
+      // 
+      // EstimatedValuesView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EstimatedValuesView";
+      this.Size = new System.Drawing.Size(310, 285);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionEstimatedValuesView.cs	(revision 15281)
@@ -0,0 +1,80 @@
+﻿#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.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Views;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.Views {
+  [View("Estimated Values")]
+  [Content(typeof(IConfidenceRegressionSolution), false)]
+  public partial class ConfidenceRegressionSolutionEstimatedValuesView : RegressionSolutionEstimatedValuesView {
+    private const string ESTIMATEDVARIANCES_SERIES_NAME = "Estimated Variances (all)";
+    private const string ESTIMATEDVARIANCES_TRAINING_SERIES_NAME = "Estimated Variances (training)";
+    private const string ESTIMATEDVARIANCES_TEST_SERIES_NAME = "Estimated Variances (test)";
+
+    public new IConfidenceRegressionSolution Content {
+      get { return (IConfidenceRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ConfidenceRegressionSolutionEstimatedValuesView()
+      : base() {
+      InitializeComponent();
+    }
+
+
+    protected override StringMatrix CreateValueMatrix() {
+      var matrix = base.CreateValueMatrix();
+
+      var columnNames = matrix.ColumnNames.Concat(new[] { ESTIMATEDVARIANCES_SERIES_NAME, ESTIMATEDVARIANCES_TRAINING_SERIES_NAME, ESTIMATEDVARIANCES_TEST_SERIES_NAME }).ToList();
+      ((IStringConvertibleMatrix)matrix).Columns += 3;
+      matrix.ColumnNames = columnNames;
+
+      var trainingRows = Content.ProblemData.TrainingIndices;
+      var testRows = Content.ProblemData.TestIndices;
+
+      var estimated_var = Content.EstimatedVariances.GetEnumerator();
+      var estimated_var_training = Content.GetEstimatedVariances(trainingRows).GetEnumerator();
+      var estimated_var_test = Content.GetEstimatedVariances(testRows).GetEnumerator();
+
+      foreach (var row in Enumerable.Range(0, Content.ProblemData.Dataset.Rows)) {
+        estimated_var.MoveNext();
+        matrix[row, 8] = estimated_var.Current.ToString();
+      }
+
+      foreach (var row in Content.ProblemData.TrainingIndices) {
+        estimated_var_training.MoveNext();
+        matrix[row, 9] = estimated_var_training.Current.ToString();
+      }
+
+      foreach (var row in Content.ProblemData.TestIndices) {
+        estimated_var_test.MoveNext();
+        matrix[row, 10] = estimated_var_test.Current.ToString();
+      }
+
+
+      return matrix;
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.Designer.cs	(revision 15281)
@@ -0,0 +1,87 @@
+﻿#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.Algorithms.DataAnalysis.Views {
+  partial class ConfidenceRegressionSolutionLineChartView {
+    /// <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() {
+      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();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(358, 225);
+      this.chart.TabIndex = 0;
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // RegressionSolutionLineChartView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionLineChartView";
+      this.Size = new System.Drawing.Size(358, 225);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/ConfidenceRegressionSolutionLineChartView.cs	(revision 15281)
@@ -0,0 +1,358 @@
+﻿#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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Problems.DataAnalysis.Views;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.Views {
+  [View("Line Chart (95% confidence interval)")]
+  [Content(typeof(IConfidenceRegressionSolution))]
+  public partial class ConfidenceRegressionSolutionLineChartView : DataAnalysisSolutionEvaluationView {
+    private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
+    private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
+    private const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Values (test)";
+    private const string ESTIMATEDVALUES_ALL_SERIES_NAME = "Estimated Values (all samples)";
+
+    public new IConfidenceRegressionSolution Content {
+      get { return (IConfidenceRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ConfidenceRegressionSolutionLineChartView()
+      : base() {
+      InitializeComponent();
+      //configure axis
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 1;
+
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorY.Interval = 0;
+    }
+
+    private void RedrawChart() {
+      this.chart.Series.Clear();
+      if (Content != null) {
+        this.chart.ChartAreas[0].AxisX.Minimum = 0;
+        this.chart.ChartAreas[0].AxisX.Maximum = Content.ProblemData.Dataset.Rows - 1;
+
+        // training series
+        this.chart.Series.Add(ESTIMATEDVALUES_TRAINING_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].LegendText = ESTIMATEDVALUES_TRAINING_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.Range;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].EmptyPointStyle.Color = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Color;
+        var mean = Content.EstimatedTrainingValues.ToArray();
+        var s2 = Content.EstimatedTrainingVariances.ToArray();
+        var lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+        var upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TrainingIndices.ToArray(), lower, upper);
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
+
+        // test series
+        this.chart.Series.Add(ESTIMATEDVALUES_TEST_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].LegendText = ESTIMATEDVALUES_TEST_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.Range;
+
+        mean = Content.EstimatedTestValues.ToArray();
+        s2 = Content.EstimatedTestVariances.ToArray();
+        lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+        upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TestIndices.ToArray(), lower, upper);
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Tag = Content;
+
+        // series of remaining points
+        int[] allIndices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
+        mean = Content.EstimatedValues.ToArray();
+        s2 = Content.EstimatedVariances.ToArray();
+        lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+        upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+        List<double> allLower = allIndices.Select(index => lower[index]).ToList();
+        List<double> allUpper = allIndices.Select(index => upper[index]).ToList();
+        this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.Range;
+        if (allIndices.Count() > 0) {
+          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allLower, allUpper);
+          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        }
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
+
+        // target
+        this.chart.Series.Add(TARGETVARIABLE_SERIES_NAME);
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].LegendText = TARGETVARIABLE_SERIES_NAME;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.DataBindXY(Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray(),
+          Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray());
+
+        this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+
+
+        // the series have been added in different order than in the normal line chart 
+        // --> adapt coloring;
+        chart.ApplyPaletteColors();
+        this.chart.Palette = ChartColorPalette.None;
+        var s0Color = chart.Series[0].Color;
+        var s1Color = chart.Series[1].Color;
+        var s2Color = chart.Series[2].Color;
+        var s3Color = chart.Series[3].Color;
+        this.chart.PaletteCustomColors = new Color[] { s1Color, s2Color, s3Color, s0Color };
+
+        // set the y-axis
+        var axisY = this.chart.ChartAreas[0].AxisY;
+        axisY.Title = Content.ProblemData.TargetVariable;
+        double min = double.MaxValue, max = double.MinValue;
+        foreach (var point in chart.Series.SelectMany(x => x.Points)) {
+          if (!point.YValues.Any() || double.IsInfinity(point.YValues[0]) || double.IsNaN(point.YValues[0]))
+            continue;
+          var y = point.YValues[0];
+          if (y < min)
+            min = y;
+          if (y > max)
+            max = y;
+        }
+
+        double axisMin, axisMax, axisInterval;
+        ChartUtil.CalculateOptimalAxisInterval(min, max, out axisMin, out axisMax, out axisInterval);
+        axisY.Minimum = axisMin;
+        axisY.Maximum = axisMax;
+        axisY.Interval = axisInterval;
+
+        UpdateCursorInterval();
+        this.UpdateStripLines();
+      }
+    }
+
+    private void InsertEmptyPoints(Series series) {
+      int i = 0;
+      while (i < series.Points.Count - 1) {
+        if (series.Points[i].IsEmpty) {
+          ++i;
+          continue;
+        }
+
+        var p1 = series.Points[i];
+        var p2 = series.Points[i + 1];
+        // check for consecutive indices
+        if ((int)p2.XValue - (int)p1.XValue != 1) {
+          // insert an empty point between p1 and p2 so that the line will be invisible (transparent)
+          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), new double[] { 0.0, 0.0 }) { IsEmpty = true };
+          // insert 
+          series.Points.Insert(i + 1, p);
+        }
+        ++i;
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      var targetValues = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
+      double targetValuesRange = targetValues.Max() - targetValues.Min();
+      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+
+
+
+    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
+                                       result.ChartElementType == ChartElementType.Gridlines) ||
+                                       result.ChartElementType == ChartElementType.StripLines) {
+        foreach (var axis in result.ChartArea.Axes)
+          axis.ScaleView.ZoomReset(int.MaxValue);
+      }
+    }
+    #endregion
+
+    private void UpdateStripLines() {
+      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
+
+      int[] attr = new int[Content.ProblemData.Dataset.Rows + 1]; // add a virtual last row that is again empty to simplify loop further down
+      foreach (var row in Content.ProblemData.TrainingIndices) {
+        attr[row] += 1;
+      }
+      foreach (var row in Content.ProblemData.TestIndices) {
+        attr[row] += 2;
+      }
+      int start = 0;
+      int curAttr = attr[start];
+      for (int row = 0; row < attr.Length; row++) {
+        if (attr[row] != curAttr) {
+          switch (curAttr) {
+            case 0: break;
+            case 1:
+              this.CreateAndAddStripLine("Training", start, row, Color.FromArgb(40, Color.Green), Color.Transparent);
+              break;
+            case 2:
+              this.CreateAndAddStripLine("Test", start, row, Color.FromArgb(40, Color.Red), Color.Transparent);
+              break;
+            case 3:
+              this.CreateAndAddStripLine("Training and Test", start, row, Color.FromArgb(40, Color.Green), Color.FromArgb(40, Color.Red), ChartHatchStyle.WideUpwardDiagonal);
+              break;
+            default:
+              // should not happen
+              break;
+          }
+          curAttr = attr[row];
+          start = row;
+        }
+      }
+    }
+
+    private void CreateAndAddStripLine(string title, int start, int end, Color color, Color secondColor, ChartHatchStyle hatchStyle = ChartHatchStyle.None) {
+      StripLine stripLine = new StripLine();
+      stripLine.BackColor = color;
+      stripLine.BackSecondaryColor = secondColor;
+      stripLine.BackHatchStyle = hatchStyle;
+      stripLine.Text = title;
+      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
+      // strip range is [start .. end] inclusive, but we evaluate [start..end[ (end is exclusive)
+      // the strip should be by one longer (starting at start - 0.5 and ending at end + 0.5)
+      stripLine.StripWidth = end - start;
+      stripLine.IntervalOffset = start - 0.5; // start slightly to the left of the first point to clearly indicate the first point in the partition
+      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
+    }
+
+    private void ToggleSeriesData(Series series) {
+      if (series.Points.Count > 0) {  //checks if series is shown
+        if (this.chart.Series.Any(s => s != series && s.Points.Count > 0)) {
+          ClearPointsQuick(series.Points);
+        }
+      } else if (Content != null) {
+
+        IEnumerable<int> indices = null;
+        IEnumerable<double> mean = null;
+        IEnumerable<double> s2 = null;
+        double[] lower = null;
+        double[] upper = null;
+        switch (series.Name) {
+          case ESTIMATEDVALUES_ALL_SERIES_NAME:
+            indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
+            mean = Content.EstimatedValues.ToArray();
+            s2 = Content.EstimatedVariances.ToArray();
+            lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+            upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+            lower = indices.Select(index => lower[index]).ToArray();
+            upper = indices.Select(index => upper[index]).ToArray();
+            break;
+          case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
+            indices = Content.ProblemData.TrainingIndices.ToArray();
+            mean = Content.EstimatedTrainingValues.ToArray();
+            s2 = Content.EstimatedTrainingVariances.ToArray();
+            lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+            upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+            break;
+          case ESTIMATEDVALUES_TEST_SERIES_NAME:
+            indices = Content.ProblemData.TestIndices.ToArray();
+            mean = Content.EstimatedTestValues.ToArray();
+            s2 = Content.EstimatedTestVariances.ToArray();
+            lower = mean.Zip(s2, GetLowerConfBound).ToArray();
+            upper = mean.Zip(s2, GetUpperConfBound).ToArray();
+            break;
+        }
+        if (indices.Count() > 0) {
+          series.Points.DataBindXY(indices, lower, upper);
+          this.InsertEmptyPoints(series);
+          chart.Legends[series.Legend].ForeColor = Color.Black;
+          UpdateCursorInterval();
+          chart.Refresh();
+        }
+      }
+    }
+
+    private double GetLowerConfBound(double m, double s) {
+      return m - 1.96 * Math.Sqrt(s);
+    }
+
+
+    private double GetUpperConfBound(double m, double s) {
+      return m + 1.96 * Math.Sqrt(s);
+    }
+
+    // workaround as per http://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
+    private static void ClearPointsQuick(DataPointCollection points) {
+      points.SuspendUpdates();
+      while (points.Count > 0)
+        points.RemoveAt(points.Count - 1);
+      points.ResumeUpdates();
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
+        Cursor = Cursors.Hand;
+      else
+        Cursor = Cursors.Default;
+    }
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
+        ToggleSeriesData(result.Series);
+      }
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      if (chart.Series.Count != 4) return;
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelWeightsView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.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.
@@ -154,5 +154,5 @@
       }
 
-      chart.ChartAreas[0].AxisX.Title = residualComboBox.SelectedItem.ToString();
+      chart.ChartAreas[0].AxisX.Title = string.Format("{0} ({1})", residualComboBox.SelectedItem, Content.ProblemData.TargetVariable);
     }
 
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.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.
@@ -81,5 +81,5 @@
 
     protected virtual StringMatrix CreateValueMatrix() {
-      string[,] values = new string[Content.ProblemData.Dataset.Rows, 7];
+      string[,] values = new string[Content.ProblemData.Dataset.Rows, 8];
 
       double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
@@ -101,14 +101,15 @@
         estimated.MoveNext();
         double est = estimated.Current;
-        double res = Math.Abs(est - target[row]);
+        double res = target[row] - est;
         values[row, 0] = row.ToString();
         values[row, 1] = target[row].ToString();
         values[row, 2] = est.ToString();
-        values[row, 5] = Math.Abs(res).ToString();
-        values[row, 6] = Math.Abs(res / target[row]).ToString();
+        values[row, 5] = res.ToString();
+        values[row, 6] = Math.Abs(res).ToString();
+        values[row, 7] = Math.Abs(res / target[row]).ToString();
       }
 
       var matrix = new StringMatrix(values);
-      matrix.ColumnNames = new string[] { "Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME, "Absolute Error (all)", "Relative Error (all)" };
+      matrix.ColumnNames = new string[] { "Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME, "Residuals (all)", "Absolute Error (all)", "Relative Error (all)" };
       matrix.SortableView = true;
       return matrix;
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.Designer.cs	(revision 15281)
@@ -0,0 +1,135 @@
+﻿#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.Algorithms.DataAnalysis.Views {
+  partial class RegressionSolutionGradientView {
+    /// <summary> 
+    /// Required designer variableNames.
+    /// </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.splitContainer = new System.Windows.Forms.SplitContainer();
+      this._partialDependencePlot = new HeuristicLab.Problems.DataAnalysis.Views.PartialDependencePlot();
+      this.configurationGroupBox = new System.Windows.Forms.GroupBox();
+      this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.configurationGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this._partialDependencePlot);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.configurationGroupBox);
+      this.splitContainer.Size = new System.Drawing.Size(715, 591);
+      this.splitContainer.SplitterDistance = 376;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // _partialDependencePlot
+      // 
+      this._partialDependencePlot.Dock = System.Windows.Forms.DockStyle.Fill;
+      this._partialDependencePlot.DrawingSteps = 1000;
+      this._partialDependencePlot.Location = new System.Drawing.Point(0, 0);
+      this._partialDependencePlot.Name = "_partialDependencePlot";
+      this._partialDependencePlot.ShowCursor = false;
+      this._partialDependencePlot.ShowLegend = false;
+      this._partialDependencePlot.Size = new System.Drawing.Size(715, 376);
+      this._partialDependencePlot.TabIndex = 0;
+      this._partialDependencePlot.XAxisTicks = 10;
+      this._partialDependencePlot.YAxisTicks = 5;
+      // 
+      // configurationGroupBox
+      // 
+      this.configurationGroupBox.Controls.Add(this.tableLayoutPanel);
+      this.configurationGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.configurationGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.configurationGroupBox.Name = "configurationGroupBox";
+      this.configurationGroupBox.Size = new System.Drawing.Size(715, 211);
+      this.configurationGroupBox.TabIndex = 1;
+      this.configurationGroupBox.TabStop = false;
+      this.configurationGroupBox.Text = "Configuration";
+      // 
+      // tableLayoutPanel
+      // 
+      this.tableLayoutPanel.AutoScroll = true;
+      this.tableLayoutPanel.ColumnCount = 1;
+      this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
+      this.tableLayoutPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tableLayoutPanel.Location = new System.Drawing.Point(3, 16);
+      this.tableLayoutPanel.Name = "tableLayoutPanel";
+      this.tableLayoutPanel.RowCount = 1;
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle());
+      this.tableLayoutPanel.Size = new System.Drawing.Size(709, 192);
+      this.tableLayoutPanel.TabIndex = 0;
+      // 
+      // RegressionSolutionGradientView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "RegressionSolutionGradientView";
+      this.Size = new System.Drawing.Size(715, 591);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.configurationGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.GroupBox configurationGroupBox;
+    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+    private Problems.DataAnalysis.Views.PartialDependencePlot _partialDependencePlot;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionGradientView.cs	(revision 15281)
@@ -0,0 +1,223 @@
+﻿#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.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Algorithms.DataAnalysis.Views {
+  [View("Gradient View")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionGradientView : ItemView {
+    private const int DrawingSteps = 1000;
+
+    private readonly List<string> variableNames;
+    private readonly ObservableList<DensityTrackbar> trackbars;
+    private ModifiableDataset sharedFixedVariables;
+
+    private int ActiveDimension {
+      get { return trackbars.FindIndex(tb => tb.Checked); }
+    }
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionSolutionGradientView()
+      : base() {
+      variableNames = new List<string>();
+
+      trackbars = new ObservableList<DensityTrackbar>();
+      trackbars.ItemsAdded += (sender, args) => {
+        args.Items.Select(i => i.Value).ForEach(RegisterEvents);
+      };
+      trackbars.ItemsRemoved += (sender, args) => {
+        args.Items.Select(i => i.Value).ForEach(DeregisterEvents);
+      };
+      trackbars.CollectionReset += (sender, args) => {
+        args.OldItems.Select(i => i.Value).ForEach(DeregisterEvents);
+        args.Items.Select(i => i.Value).ForEach(RegisterEvents);
+      };
+
+      InitializeComponent();
+
+      // Avoid additional horizontal scrollbar
+      var vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
+      tableLayoutPanel.Padding = new Padding(0, 0, vertScrollWidth, 0);
+    }
+
+    private async void UpdateConfigurationControls() {
+      variableNames.Clear();
+      trackbars.Clear();
+
+      tableLayoutPanel.SuspendRepaint();
+      tableLayoutPanel.SuspendLayout();
+
+      tableLayoutPanel.RowCount = 0;
+      tableLayoutPanel.Controls.Clear();
+
+      if (Content == null) {
+        tableLayoutPanel.ResumeLayout(false);
+        tableLayoutPanel.ResumeRepaint(false);
+        return;
+      }
+
+      variableNames.AddRange(Content.ProblemData.AllowedInputVariables);
+
+      var newTrackbars = CreateConfiguration();
+
+      sharedFixedVariables = new ModifiableDataset(variableNames, newTrackbars.Select(tb => new List<double>(1) { (double)tb.Value }));
+      _partialDependencePlot.Configure(new[] { Content }, sharedFixedVariables, variableNames.First(), DrawingSteps);
+      await _partialDependencePlot.RecalculateAsync();
+
+      // Add to table and observable lists
+      tableLayoutPanel.RowCount = variableNames.Count;
+      while (tableLayoutPanel.RowStyles.Count < variableNames.Count)
+        tableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
+      for (int i = 0; i < newTrackbars.Count; i++) {
+        // events registered automatically
+        trackbars.Add(newTrackbars[i]);
+        tableLayoutPanel.Controls.Add(newTrackbars[i], 0, i);
+      }
+
+      tableLayoutPanel.ResumeLayout(true);
+      tableLayoutPanel.ResumeRepaint(true);
+
+      // Init Y-axis range
+      var problemData = Content.ProblemData;
+      double min = double.MaxValue, max = double.MinValue;
+      var trainingTarget = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices);
+      foreach (var t in trainingTarget) {
+        if (t < min) min = t;
+        if (t > max) max = t;
+      }
+      double range = max - min;
+      const double scale = 1.0 / 3.0;
+      double axisMin, axisMax, axisInterval;
+      ChartUtil.CalculateAxisInterval(min - scale * range, max + scale * range, 5, out axisMin, out axisMax, out axisInterval);
+      _partialDependencePlot.FixedYAxisMin = axisMin;
+      _partialDependencePlot.FixedYAxisMax = axisMax;
+
+      trackbars.First().Checked = true;
+    }
+
+    private IList<DensityTrackbar> CreateConfiguration() {
+      var ranges = new List<DoubleLimit>();
+      foreach (string variableName in variableNames) {
+        var values = Content.ProblemData.Dataset.GetDoubleValues(variableName, Content.ProblemData.AllIndices);
+        double min, max, interval;
+        ChartUtil.CalculateAxisInterval(values.Min(), values.Max(), 10, out min, out max, out interval);
+        ranges.Add(new DoubleLimit(min, max));
+      }
+
+      var newTrackbars = new List<DensityTrackbar>();
+      for (int i = 0; i < variableNames.Count; i++) {
+        var name = variableNames[i];
+        var trainingData = Content.ProblemData.Dataset.GetDoubleValues(name, Content.ProblemData.TrainingIndices).ToList();
+
+        var dimensionTrackbar = new DensityTrackbar(name, ranges[i], trainingData) {
+          Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right
+        };
+        newTrackbars.Add(dimensionTrackbar);
+      }
+
+      return newTrackbars;
+    }
+
+    private void RegisterEvents(DensityTrackbar trackbar) {
+      trackbar.CheckedChanged += trackbar_CheckedChanged;
+      trackbar.ValueChanged += trackbar_ValueChanged;
+      trackbar.LimitsChanged += trackbar_LimitsChanged;
+    }
+    private void DeregisterEvents(DensityTrackbar trackbar) {
+      trackbar.CheckedChanged -= trackbar_CheckedChanged;
+      trackbar.ValueChanged -= trackbar_ValueChanged;
+      trackbar.LimitsChanged -= trackbar_LimitsChanged;
+    }
+
+    private async void trackbar_CheckedChanged(object sender, EventArgs e) {
+      var trackBar = sender as DensityTrackbar;
+      if (trackBar == null || !trackBar.Checked) return;
+      // Uncheck all others
+      foreach (var tb in trackbars.Except(new[] { trackBar }))
+        tb.Checked = false;
+      _partialDependencePlot.FreeVariable = variableNames[trackbars.IndexOf(trackBar)];
+      await _partialDependencePlot.RecalculateAsync();
+    }
+
+    private async void trackbar_LimitsChanged(object sender, EventArgs e) {
+      var trackBar = sender as DensityTrackbar;
+      if (trackBar == null || !trackBar.Checked) return;
+      _partialDependencePlot.FixedXAxisMin = trackBar.Limits.Lower;
+      _partialDependencePlot.FixedXAxisMax = trackBar.Limits.Upper;
+      await _partialDependencePlot.RecalculateAsync();
+    }
+
+    private async void trackbar_ValueChanged(object sender, EventArgs e) {
+      var trackBar = sender as DensityTrackbar;
+      if (trackBar == null) return;
+      sharedFixedVariables.SetVariableValue((double)trackBar.Value, variableNames[trackbars.IndexOf(trackBar)], 0);
+      await _partialDependencePlot.RecalculateAsync();
+    }
+
+    #region Events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += Content_ModelChanged;
+      Content.ProblemDataChanged += Content_ProblemDataChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= Content_ModelChanged;
+      Content.ProblemDataChanged -= Content_ProblemDataChanged;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateConfigurationControls();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      UpdateConfigurationControls();
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      UpdateConfigurationControls();
+    }
+    #endregion
+  }
+
+  internal static class Extensions {
+    public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) {
+      foreach (T item in source)
+        action(item);
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.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.
@@ -44,38 +44,4 @@
     /// </summary>
     private void InitializeComponent() {
-      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();
-      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
-      this.SuspendLayout();
-      // 
-      // chart
-      // 
-      chartArea1.Name = "ChartArea";
-      this.chart.ChartAreas.Add(chartArea1);
-      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
-      legend1.Alignment = System.Drawing.StringAlignment.Center;
-      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend1.Name = "Default";
-      this.chart.Legends.Add(legend1);
-      this.chart.Location = new System.Drawing.Point(0, 0);
-      this.chart.Name = "chart";
-      this.chart.Size = new System.Drawing.Size(358, 225);
-      this.chart.TabIndex = 0;
-      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
-      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
-      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
-      // 
-      // RegressionSolutionLineChartView
-      // 
-      this.AllowDrop = true;
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Controls.Add(this.chart);
-      this.Name = "RegressionSolutionLineChartView";
-      this.Size = new System.Drawing.Size(358, 225);
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
-      this.ResumeLayout(false);
 
     }
@@ -83,5 +49,4 @@
     #endregion
 
-    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
   }
 }
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.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.
@@ -19,265 +19,35 @@
  */
 #endregion
+
 using System;
-using System.Collections.Generic;
-using System.Drawing;
 using System.Linq;
-using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
 using HeuristicLab.MainForm;
+
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   [View("Line Chart")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionLineChartView : DataAnalysisSolutionEvaluationView {
-    private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
-    private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
-    private const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Values (test)";
-    private const string ESTIMATEDVALUES_ALL_SERIES_NAME = "Estimated Values (all samples)";
+  public partial class RegressionSolutionLineChartView : RegressionSolutionLineChartViewBase {
 
-    public new IRegressionSolution Content {
-      get { return (IRegressionSolution)base.Content; }
-      set { base.Content = value; }
-    }
 
     public RegressionSolutionLineChartView()
       : base() {
       InitializeComponent();
-      //configure axis
-      this.chart.CustomizeAllChartAreas();
-      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
-      this.chart.ChartAreas[0].CursorX.Interval = 1;
-
-      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].CursorY.Interval = 0;
     }
 
-    private void RedrawChart() {
-      this.chart.Series.Clear();
-      if (Content != null) {
-        this.chart.ChartAreas[0].AxisX.Minimum = 0;
-        this.chart.ChartAreas[0].AxisX.Maximum = Content.ProblemData.Dataset.Rows - 1;
-
-        this.chart.Series.Add(TARGETVARIABLE_SERIES_NAME);
-        this.chart.Series[TARGETVARIABLE_SERIES_NAME].LegendText = Content.ProblemData.TargetVariable;
-        this.chart.Series[TARGETVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.DataBindXY(Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray(),
-          Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray());
-        // training series
-        this.chart.Series.Add(ESTIMATEDVALUES_TRAINING_SERIES_NAME);
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].LegendText = ESTIMATEDVALUES_TRAINING_SERIES_NAME;
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].EmptyPointStyle.Color = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Color;
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TrainingIndices.ToArray(), Content.EstimatedTrainingValues.ToArray());
-        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME]);
-        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
-        // test series
-        this.chart.Series.Add(ESTIMATEDVALUES_TEST_SERIES_NAME);
-        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].LegendText = ESTIMATEDVALUES_TEST_SERIES_NAME;
-        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TestIndices.ToArray(), Content.EstimatedTestValues.ToArray());
-        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME]);
-        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Tag = Content;
-        // series of remaining points
-        int[] allIndices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
-        var estimatedValues = Content.EstimatedValues.ToArray();
-        List<double> allEstimatedValues = allIndices.Select(index => estimatedValues[index]).ToList();
-        this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.FastLine;
-        if (allEstimatedValues.Count > 0) {
-          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
-          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
-        }
-        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
-        this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
-
-        UpdateCursorInterval();
-        this.UpdateStripLines();
-      }
+    protected override void GetTrainingSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TrainingIndices.ToArray();
+      y = Content.EstimatedTrainingValues.ToArray();
     }
 
-    private void InsertEmptyPoints(Series series) {
-      int i = 0;
-      while (i < series.Points.Count - 1) {
-        if (series.Points[i].IsEmpty) {
-          ++i;
-          continue;
-        }
-
-        var p1 = series.Points[i];
-        var p2 = series.Points[i + 1];
-        // check for consecutive indices
-        if ((int)p2.XValue - (int)p1.XValue != 1) {
-          // insert an empty point between p1 and p2 so that the line will be invisible (transparent)
-          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), 0.0) { IsEmpty = true };
-          series.Points.Insert(i + 1, p);
-        }
-        ++i;
-      }
+    protected override void GetTestSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TestIndices.ToArray();
+      y = Content.EstimatedTestValues.ToArray();
     }
 
-    private void UpdateCursorInterval() {
-      var estimatedValues = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
-      var targetValues = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
-      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
-      double targetValuesRange = targetValues.Max() - targetValues.Min();
-      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
-      double digits = (int)Math.Log10(interestingValuesRange) - 3;
-      double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
-      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
-    }
-
-    #region events
-    protected override void RegisterContentEvents() {
-      base.RegisterContentEvents();
-      Content.ModelChanged += new EventHandler(Content_ModelChanged);
-      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
-    }
-    protected override void DeregisterContentEvents() {
-      base.DeregisterContentEvents();
-      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
-      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      RedrawChart();
-    }
-    private void Content_ProblemDataChanged(object sender, EventArgs e) {
-      RedrawChart();
-    }
-    private void Content_ModelChanged(object sender, EventArgs e) {
-      RedrawChart();
-    }
-
-
-
-    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
-                                       result.ChartElementType == ChartElementType.Gridlines) ||
-                                       result.ChartElementType == ChartElementType.StripLines) {
-        foreach (var axis in result.ChartArea.Axes)
-          axis.ScaleView.ZoomReset(int.MaxValue);
-      }
-    }
-    #endregion
-
-    private void UpdateStripLines() {
-      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
-
-      int[] attr = new int[Content.ProblemData.Dataset.Rows + 1]; // add a virtual last row that is again empty to simplify loop further down
-      foreach (var row in Content.ProblemData.TrainingIndices) {
-        attr[row] += 1;
-      }
-      foreach (var row in Content.ProblemData.TestIndices) {
-        attr[row] += 2;
-      }
-      int start = 0;
-      int curAttr = attr[start];
-      for (int row = 0; row < attr.Length; row++) {
-        if (attr[row] != curAttr) {
-          switch (curAttr) {
-            case 0: break;
-            case 1:
-              this.CreateAndAddStripLine("Training", start, row, Color.FromArgb(40, Color.Green), Color.Transparent);
-              break;
-            case 2:
-              this.CreateAndAddStripLine("Test", start, row, Color.FromArgb(40, Color.Red), Color.Transparent);
-              break;
-            case 3:
-              this.CreateAndAddStripLine("Training and Test", start, row, Color.FromArgb(40, Color.Green), Color.FromArgb(40, Color.Red), ChartHatchStyle.WideUpwardDiagonal);
-              break;
-            default:
-              // should not happen
-              break;
-          }
-          curAttr = attr[row];
-          start = row;
-        }
-      }
-    }
-
-    private void CreateAndAddStripLine(string title, int start, int end, Color color, Color secondColor, ChartHatchStyle hatchStyle = ChartHatchStyle.None) {
-      StripLine stripLine = new StripLine();
-      stripLine.BackColor = color;
-      stripLine.BackSecondaryColor = secondColor;
-      stripLine.BackHatchStyle = hatchStyle;
-      stripLine.Text = title;
-      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
-      // strip range is [start .. end] inclusive, but we evaluate [start..end[ (end is exclusive)
-      // the strip should be by one longer (starting at start - 0.5 and ending at end + 0.5)
-      stripLine.StripWidth = end - start;
-      stripLine.IntervalOffset = start - 0.5; // start slightly to the left of the first point to clearly indicate the first point in the partition
-      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
-    }
-
-    private void ToggleSeriesData(Series series) {
-      if (series.Points.Count > 0) {  //checks if series is shown
-        if (this.chart.Series.Any(s => s != series && s.Points.Count > 0)) {
-          ClearPointsQuick(series.Points);
-        }
-      } else if (Content != null) {
-        string targetVariableName = Content.ProblemData.TargetVariable;
-
-        IEnumerable<int> indices = null;
-        double[] predictedValues = null;
-        switch (series.Name) {
-          case ESTIMATEDVALUES_ALL_SERIES_NAME:
-            indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
-            var estimatedValues = Content.EstimatedValues.ToArray();
-            predictedValues = indices.Select(index => estimatedValues[index]).ToArray();
-            break;
-          case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
-            indices = Content.ProblemData.TrainingIndices.ToArray();
-            predictedValues = Content.EstimatedTrainingValues.ToArray();
-            break;
-          case ESTIMATEDVALUES_TEST_SERIES_NAME:
-            indices = Content.ProblemData.TestIndices.ToArray();
-            predictedValues = Content.EstimatedTestValues.ToArray();
-            break;
-        }
-        if (predictedValues.Length > 0) {
-          series.Points.DataBindXY(indices, predictedValues);
-          this.InsertEmptyPoints(series);
-        }
-        chart.Legends[series.Legend].ForeColor = Color.Black;
-        UpdateCursorInterval();
-        chart.Refresh();
-      }
-    }
-
-    // workaround as per http://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
-    private static void ClearPointsQuick(DataPointCollection points) {
-      points.SuspendUpdates();
-      while (points.Count > 0)
-        points.RemoveAt(points.Count - 1);
-      points.ResumeUpdates();
-    }
-
-    private void chart_MouseMove(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
-        Cursor = Cursors.Hand;
-      else
-        Cursor = Cursors.Default;
-    }
-    private void chart_MouseDown(object sender, MouseEventArgs e) {
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
-        ToggleSeriesData(result.Series);
-      }
-    }
-
-    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
-      if (chart.Series.Count != 4) return;
-      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
-      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+    protected override void GetAllValuesSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.AllIndices.ToArray();
+      y = Content.EstimatedValues.ToArray();
     }
   }
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.Designer.cs	(revision 15281)
@@ -0,0 +1,87 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionLineChartViewBase {
+    /// <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() {
+      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();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(358, 225);
+      this.chart.TabIndex = 0;
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // RegressionSolutionLineChartView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionLineChartView";
+      this.Size = new System.Drawing.Size(358, 225);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartViewBase.cs	(revision 15281)
@@ -0,0 +1,315 @@
+﻿#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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Line Chart")]
+  [Content(typeof(IRegressionSolution))]
+  public abstract partial class RegressionSolutionLineChartViewBase : DataAnalysisSolutionEvaluationView {
+    protected const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
+    protected const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
+    protected const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Values (test)";
+    protected const string ESTIMATEDVALUES_ALL_SERIES_NAME = "Estimated Values (all samples)";
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected RegressionSolutionLineChartViewBase()
+      : base() {
+      InitializeComponent();
+      //configure axis
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 1;
+
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorY.Interval = 0;
+    }
+
+    protected abstract void GetTrainingSeries(out int[] idx, out double[] y);
+
+    protected abstract void GetTestSeries(out int[] x, out double[] y);
+
+    protected abstract void GetAllValuesSeries(out int[] x, out double[] y);
+
+    protected virtual void RedrawChart() {
+      this.chart.Series.Clear();
+      if (Content != null) {
+        this.chart.ChartAreas[0].AxisX.Minimum = 0;
+        this.chart.ChartAreas[0].AxisX.Maximum = Content.ProblemData.Dataset.Rows - 1;
+
+        this.chart.Series.Add(TARGETVARIABLE_SERIES_NAME);
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].LegendText = TARGETVARIABLE_SERIES_NAME;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.DataBindXY(Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray(),
+          Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray());
+        // training series
+        this.chart.Series.Add(ESTIMATEDVALUES_TRAINING_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].LegendText = ESTIMATEDVALUES_TRAINING_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].EmptyPointStyle.Color = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Color;
+        int[] trainingIdx;
+        double[] trainingY;
+        GetTrainingSeries(out trainingIdx, out trainingY);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(trainingIdx, trainingY);
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
+
+        // test series
+        this.chart.Series.Add(ESTIMATEDVALUES_TEST_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].LegendText = ESTIMATEDVALUES_TEST_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        int[] testIdx;
+        double[] testY;
+        GetTestSeries(out testIdx, out testY);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(testIdx, testY);
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Tag = Content;
+
+        // series of remaining points
+        int[] allIdx;
+        double[] allEstimatedValues;
+        GetAllValuesSeries(out allIdx, out allEstimatedValues);
+
+        this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        if (allEstimatedValues.Length > 0) {
+          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIdx, allEstimatedValues);
+          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        }
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
+        this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+
+        // set the y-axis
+        var axisY = this.chart.ChartAreas[0].AxisY;
+        axisY.Title = Content.ProblemData.TargetVariable;
+        double min = double.MaxValue, max = double.MinValue;
+        foreach (var point in chart.Series.SelectMany(x => x.Points)) {
+          if (!point.YValues.Any() || double.IsInfinity(point.YValues[0]) || double.IsNaN(point.YValues[0]))
+            continue;
+          var y = point.YValues[0];
+          if (y < min)
+            min = y;
+          if (y > max)
+            max = y;
+        }
+
+        double axisMin, axisMax, axisInterval;
+        ChartUtil.CalculateOptimalAxisInterval(min, max, out axisMin, out axisMax, out axisInterval);
+        axisY.Minimum = axisMin;
+        axisY.Maximum = axisMax;
+        axisY.Interval = axisInterval;
+
+        UpdateCursorInterval();
+        this.UpdateStripLines();
+      }
+    }
+
+    private void InsertEmptyPoints(Series series) {
+      int i = 0;
+      while (i < series.Points.Count - 1) {
+        if (series.Points[i].IsEmpty) {
+          ++i;
+          continue;
+        }
+
+        var p1 = series.Points[i];
+        var p2 = series.Points[i + 1];
+        // check for consecutive indices
+        if ((int)p2.XValue - (int)p1.XValue != 1) {
+          // insert an empty point between p1 and p2 so that the line will be invisible (transparent)
+          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), 0.0) { IsEmpty = true };
+          series.Points.Insert(i + 1, p);
+        }
+        ++i;
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      var targetValues = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
+      double targetValuesRange = targetValues.Max() - targetValues.Min();
+      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+
+
+
+    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
+                                       result.ChartElementType == ChartElementType.Gridlines) ||
+                                       result.ChartElementType == ChartElementType.StripLines) {
+        foreach (var axis in result.ChartArea.Axes)
+          axis.ScaleView.ZoomReset(int.MaxValue);
+      }
+    }
+    #endregion
+
+    private void UpdateStripLines() {
+      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
+
+      int[] attr = new int[Content.ProblemData.Dataset.Rows + 1]; // add a virtual last row that is again empty to simplify loop further down
+      foreach (var row in Content.ProblemData.TrainingIndices) {
+        attr[row] += 1;
+      }
+      foreach (var row in Content.ProblemData.TestIndices) {
+        attr[row] += 2;
+      }
+      int start = 0;
+      int curAttr = attr[start];
+      for (int row = 0; row < attr.Length; row++) {
+        if (attr[row] != curAttr) {
+          switch (curAttr) {
+            case 0: break;
+            case 1:
+              this.CreateAndAddStripLine("Training", start, row, Color.FromArgb(40, Color.Green), Color.Transparent);
+              break;
+            case 2:
+              this.CreateAndAddStripLine("Test", start, row, Color.FromArgb(40, Color.Red), Color.Transparent);
+              break;
+            case 3:
+              this.CreateAndAddStripLine("Training and Test", start, row, Color.FromArgb(40, Color.Green), Color.FromArgb(40, Color.Red), ChartHatchStyle.WideUpwardDiagonal);
+              break;
+            default:
+              // should not happen
+              break;
+          }
+          curAttr = attr[row];
+          start = row;
+        }
+      }
+    }
+
+    private void CreateAndAddStripLine(string title, int start, int end, Color color, Color secondColor, ChartHatchStyle hatchStyle = ChartHatchStyle.None) {
+      StripLine stripLine = new StripLine();
+      stripLine.BackColor = color;
+      stripLine.BackSecondaryColor = secondColor;
+      stripLine.BackHatchStyle = hatchStyle;
+      stripLine.Text = title;
+      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
+      // strip range is [start .. end] inclusive, but we evaluate [start..end[ (end is exclusive)
+      // the strip should be by one longer (starting at start - 0.5 and ending at end + 0.5)
+      stripLine.StripWidth = end - start;
+      stripLine.IntervalOffset = start - 0.5; // start slightly to the left of the first point to clearly indicate the first point in the partition
+      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
+    }
+
+    public void ToggleSeriesData(Series series) {
+      if (series.Points.Count > 0) {  //checks if series is shown
+        if (this.chart.Series.Any(s => s != series && s.Points.Count > 0)) {
+          ClearPointsQuick(series.Points);
+        }
+      } else if (Content != null) {
+
+        int[] indices = null;
+        double[] predictedValues = null;
+        switch (series.Name) {
+          case ESTIMATEDVALUES_ALL_SERIES_NAME:
+            GetAllValuesSeries(out indices, out predictedValues);
+            break;
+          case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
+            GetTrainingSeries(out indices, out predictedValues);
+            break;
+          case ESTIMATEDVALUES_TEST_SERIES_NAME:
+            GetTestSeries(out indices, out predictedValues);
+            break;
+        }
+        if (predictedValues.Length > 0) {
+          series.Points.DataBindXY(indices, predictedValues);
+          this.InsertEmptyPoints(series);
+        }
+        chart.Legends[series.Legend].ForeColor = Color.Black;
+        UpdateCursorInterval();
+        chart.Refresh();
+      }
+    }
+
+    // workaround as per http://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
+    private static void ClearPointsQuick(DataPointCollection points) {
+      points.SuspendUpdates();
+      while (points.Count > 0)
+        points.RemoveAt(points.Count - 1);
+      points.ResumeUpdates();
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
+        Cursor = Cursors.Hand;
+      else
+        Cursor = Cursors.Default;
+    }
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
+        ToggleSeriesData(result.Series);
+      }
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      if (chart.Series.Count != 4) return;
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.Designer.cs	(revision 15281)
@@ -0,0 +1,271 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionPartialDependencePlotView {
+    /// <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();
+      this.variableListView = new System.Windows.Forms.ListView();
+      this.partialDependencePlotTableLayout = new System.Windows.Forms.TableLayoutPanel();
+      this.yAxisConfigGroupBox = new System.Windows.Forms.GroupBox();
+      this.limitView = new HeuristicLab.Problems.DataAnalysis.Views.DoubleLimitView();
+      this.automaticYAxisCheckBox = new System.Windows.Forms.CheckBox();
+      this.densityGroupBox = new System.Windows.Forms.GroupBox();
+      this.columnsLabel = new System.Windows.Forms.Label();
+      this.densityComboBox = new System.Windows.Forms.ComboBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.configSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.variableGroupBox = new System.Windows.Forms.GroupBox();
+      this.scrollPanel = new System.Windows.Forms.Panel();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.columnsNumericUpDown = new System.Windows.Forms.NumericUpDown();
+      this.yAxisConfigGroupBox.SuspendLayout();
+      this.densityGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.configSplitContainer)).BeginInit();
+      this.configSplitContainer.Panel1.SuspendLayout();
+      this.configSplitContainer.Panel2.SuspendLayout();
+      this.configSplitContainer.SuspendLayout();
+      this.variableGroupBox.SuspendLayout();
+      this.scrollPanel.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.columnsNumericUpDown)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // variableListView
+      // 
+      this.variableListView.CheckBoxes = true;
+      this.variableListView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variableListView.Location = new System.Drawing.Point(3, 16);
+      this.variableListView.Name = "variableListView";
+      this.variableListView.Size = new System.Drawing.Size(163, 478);
+      this.variableListView.TabIndex = 0;
+      this.variableListView.UseCompatibleStateImageBehavior = false;
+      this.variableListView.View = System.Windows.Forms.View.List;
+      this.variableListView.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.variableListView_ItemChecked);
+      // 
+      // partialDependencePlotTableLayout
+      // 
+      this.partialDependencePlotTableLayout.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.partialDependencePlotTableLayout.AutoSize = true;
+      this.partialDependencePlotTableLayout.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
+      this.partialDependencePlotTableLayout.ColumnCount = 1;
+      this.partialDependencePlotTableLayout.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
+      this.partialDependencePlotTableLayout.Location = new System.Drawing.Point(0, 0);
+      this.partialDependencePlotTableLayout.Name = "partialDependencePlotTableLayout";
+      this.partialDependencePlotTableLayout.RowCount = 1;
+      this.partialDependencePlotTableLayout.RowStyles.Add(new System.Windows.Forms.RowStyle());
+      this.partialDependencePlotTableLayout.Size = new System.Drawing.Size(542, 0);
+      this.partialDependencePlotTableLayout.TabIndex = 2;
+      // 
+      // yAxisConfigGroupBox
+      // 
+      this.yAxisConfigGroupBox.Controls.Add(this.limitView);
+      this.yAxisConfigGroupBox.Controls.Add(this.automaticYAxisCheckBox);
+      this.yAxisConfigGroupBox.Dock = System.Windows.Forms.DockStyle.Top;
+      this.yAxisConfigGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.yAxisConfigGroupBox.Name = "yAxisConfigGroupBox";
+      this.yAxisConfigGroupBox.Size = new System.Drawing.Size(169, 77);
+      this.yAxisConfigGroupBox.TabIndex = 2;
+      this.yAxisConfigGroupBox.TabStop = false;
+      this.yAxisConfigGroupBox.Text = "Y-Axis";
+      // 
+      // limitView
+      // 
+      this.limitView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.limitView.Caption = "DoubleLimit View";
+      this.limitView.Content = null;
+      this.limitView.Location = new System.Drawing.Point(6, 20);
+      this.limitView.Name = "limitView";
+      this.limitView.ReadOnly = false;
+      this.limitView.Size = new System.Drawing.Size(157, 47);
+      this.limitView.TabIndex = 1;
+      // 
+      // automaticYAxisCheckBox
+      // 
+      this.automaticYAxisCheckBox.AutoSize = true;
+      this.automaticYAxisCheckBox.Location = new System.Drawing.Point(49, -1);
+      this.automaticYAxisCheckBox.Name = "automaticYAxisCheckBox";
+      this.automaticYAxisCheckBox.Size = new System.Drawing.Size(73, 17);
+      this.automaticYAxisCheckBox.TabIndex = 0;
+      this.automaticYAxisCheckBox.Text = "Automatic";
+      this.automaticYAxisCheckBox.UseVisualStyleBackColor = true;
+      this.automaticYAxisCheckBox.CheckedChanged += new System.EventHandler(this.automaticYAxisCheckBox_CheckedChanged);
+      // 
+      // densityGroupBox
+      // 
+      this.densityGroupBox.Controls.Add(this.columnsNumericUpDown);
+      this.densityGroupBox.Controls.Add(this.columnsLabel);
+      this.densityGroupBox.Controls.Add(this.densityComboBox);
+      this.densityGroupBox.Controls.Add(this.label1);
+      this.densityGroupBox.Dock = System.Windows.Forms.DockStyle.Top;
+      this.densityGroupBox.Location = new System.Drawing.Point(0, 77);
+      this.densityGroupBox.Name = "densityGroupBox";
+      this.densityGroupBox.Size = new System.Drawing.Size(169, 74);
+      this.densityGroupBox.TabIndex = 3;
+      this.densityGroupBox.TabStop = false;
+      this.densityGroupBox.Text = "Settings";
+      // 
+      // columnsLabel
+      // 
+      this.columnsLabel.AutoSize = true;
+      this.columnsLabel.Location = new System.Drawing.Point(7, 49);
+      this.columnsLabel.Name = "columnsLabel";
+      this.columnsLabel.Size = new System.Drawing.Size(50, 13);
+      this.columnsLabel.TabIndex = 0;
+      this.columnsLabel.Text = "Columns:";
+      // 
+      // densityComboBox
+      // 
+      this.densityComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.densityComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.densityComboBox.FormattingEnabled = true;
+      this.densityComboBox.Items.AddRange(new object[] {
+            "None",
+            "Training",
+            "Test",
+            "All"});
+      this.densityComboBox.Location = new System.Drawing.Point(66, 19);
+      this.densityComboBox.Name = "densityComboBox";
+      this.densityComboBox.Size = new System.Drawing.Size(94, 21);
+      this.densityComboBox.TabIndex = 0;
+      this.densityComboBox.SelectedIndexChanged += new System.EventHandler(this.densityComboBox_SelectedIndexChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(7, 22);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(45, 13);
+      this.label1.TabIndex = 0;
+      this.label1.Text = "Density:";
+      // 
+      // configSplitContainer
+      // 
+      this.configSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.configSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.configSplitContainer.Location = new System.Drawing.Point(0, 0);
+      this.configSplitContainer.Name = "configSplitContainer";
+      // 
+      // configSplitContainer.Panel1
+      // 
+      this.configSplitContainer.Panel1.Controls.Add(this.variableGroupBox);
+      this.configSplitContainer.Panel1.Controls.Add(this.densityGroupBox);
+      this.configSplitContainer.Panel1.Controls.Add(this.yAxisConfigGroupBox);
+      // 
+      // configSplitContainer.Panel2
+      // 
+      this.configSplitContainer.Panel2.Controls.Add(this.scrollPanel);
+      this.configSplitContainer.Size = new System.Drawing.Size(715, 648);
+      this.configSplitContainer.SplitterDistance = 169;
+      this.configSplitContainer.TabIndex = 0;
+      this.configSplitContainer.TabStop = false;
+      // 
+      // variableGroupBox
+      // 
+      this.variableGroupBox.Controls.Add(this.variableListView);
+      this.variableGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variableGroupBox.Location = new System.Drawing.Point(0, 151);
+      this.variableGroupBox.Name = "variableGroupBox";
+      this.variableGroupBox.Size = new System.Drawing.Size(169, 497);
+      this.variableGroupBox.TabIndex = 1;
+      this.variableGroupBox.TabStop = false;
+      this.variableGroupBox.Text = "Variables";
+      // 
+      // scrollPanel
+      // 
+      this.scrollPanel.Controls.Add(this.partialDependencePlotTableLayout);
+      this.scrollPanel.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.scrollPanel.Location = new System.Drawing.Point(0, 0);
+      this.scrollPanel.Name = "scrollPanel";
+      this.scrollPanel.Size = new System.Drawing.Size(542, 648);
+      this.scrollPanel.TabIndex = 0;
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      // 
+      // columnsNumericUpDown
+      // 
+      this.columnsNumericUpDown.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.columnsNumericUpDown.Location = new System.Drawing.Point(66, 46);
+      this.columnsNumericUpDown.Minimum = new decimal(new int[] {
+            1,
+            0,
+            0,
+            0});
+      this.columnsNumericUpDown.Name = "columnsNumericUpDown";
+      this.columnsNumericUpDown.Size = new System.Drawing.Size(94, 20);
+      this.columnsNumericUpDown.TabIndex = 1;
+      this.columnsNumericUpDown.Value = new decimal(new int[] {
+            4,
+            0,
+            0,
+            0});
+      this.columnsNumericUpDown.ValueChanged += new System.EventHandler(this.columnsNumericUpDown_ValueChanged);
+      // 
+      // RegressionSolutionPartialDependencePlotView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.configSplitContainer);
+      this.Name = "RegressionSolutionPartialDependencePlotView";
+      this.Size = new System.Drawing.Size(715, 648);
+      this.yAxisConfigGroupBox.ResumeLayout(false);
+      this.yAxisConfigGroupBox.PerformLayout();
+      this.densityGroupBox.ResumeLayout(false);
+      this.densityGroupBox.PerformLayout();
+      this.configSplitContainer.Panel1.ResumeLayout(false);
+      this.configSplitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.configSplitContainer)).EndInit();
+      this.configSplitContainer.ResumeLayout(false);
+      this.variableGroupBox.ResumeLayout(false);
+      this.scrollPanel.ResumeLayout(false);
+      this.scrollPanel.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.columnsNumericUpDown)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ListView variableListView;
+    private System.Windows.Forms.TableLayoutPanel partialDependencePlotTableLayout;
+    private System.Windows.Forms.GroupBox yAxisConfigGroupBox;
+    private System.Windows.Forms.CheckBox automaticYAxisCheckBox;
+    private DoubleLimitView limitView;
+    private System.Windows.Forms.GroupBox densityGroupBox;
+    private System.Windows.Forms.ComboBox densityComboBox;
+    private System.Windows.Forms.SplitContainer configSplitContainer;
+    private System.Windows.Forms.GroupBox variableGroupBox;
+    private System.Windows.Forms.Panel scrollPanel;
+    private System.Windows.Forms.Label columnsLabel;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.NumericUpDown columnsNumericUpDown;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionPartialDependencePlotView.cs	(revision 15281)
@@ -0,0 +1,567 @@
+﻿#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;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.Visualization.ChartControlsExtensions;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Partial Dependence Plots")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionPartialDependencePlotView : DataAnalysisSolutionEvaluationView {
+    private readonly Dictionary<string, IPartialDependencePlot> partialDependencePlots;
+    private readonly Dictionary<string, DensityChart> densityCharts;
+    private readonly Dictionary<string, Panel> groupingPanels;
+    private ModifiableDataset sharedFixedVariables;
+
+    private const int Points = 200;
+    private int MaxColumns = 4;
+
+    private IEnumerable<string> VisibleVariables {
+      get {
+        foreach (ListViewItem item in variableListView.CheckedItems)
+          yield return item.Text;
+      }
+    }
+    private IEnumerable<IPartialDependencePlot> VisiblePartialDependencePlots {
+      get { return VisibleVariables.Select(v => partialDependencePlots[v]); }
+    }
+    private IEnumerable<DensityChart> VisibleDensityCharts {
+      get { return VisibleVariables.Select(v => densityCharts[v]); }
+    }
+    private IEnumerable<Panel> VisibleChartsPanels {
+      get { return VisibleVariables.Select(v => groupingPanels[v]); }
+    }
+
+    public RegressionSolutionPartialDependencePlotView() {
+      InitializeComponent();
+      partialDependencePlots = new Dictionary<string, IPartialDependencePlot>();
+      densityCharts = new Dictionary<string, DensityChart>();
+      groupingPanels = new Dictionary<string, Panel>();
+
+      limitView.Content = new DoubleLimit(0, 1);
+      limitView.Content.ValueChanged += limit_ValueChanged;
+
+      densityComboBox.SelectedIndex = 1; // select Training
+
+      // Avoid additional horizontal scrollbar
+      var vertScrollWidth = SystemInformation.VerticalScrollBarWidth;
+      scrollPanel.Padding = new Padding(0, 0, vertScrollWidth, 0);
+      scrollPanel.AutoScroll = true;
+    }
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += solution_ModelChanged;
+    }
+
+    protected override void DeregisterContentEvents() {
+      Content.ModelChanged -= solution_ModelChanged;
+      base.DeregisterContentEvents();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) return;
+      var problemData = Content.ProblemData;
+
+      // Init Y-axis range
+      double min = double.MaxValue, max = double.MinValue;
+      var trainingTarget = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices);
+      foreach (var t in trainingTarget) {
+        if (t < min) min = t;
+        if (t > max) max = t;
+      }
+      double range = max - min;
+      const double scale = 1.0 / 3.0;
+      double axisMin, axisMax, axisInterval;
+      ChartUtil.CalculateAxisInterval(min - scale * range, max + scale * range, 5, out axisMin, out axisMax, out axisInterval);
+      automaticYAxisCheckBox.Checked = false;
+      limitView.ReadOnly = false;
+      limitView.Content.Lower = axisMin;
+      limitView.Content.Upper = axisMax;
+
+      // create dataset of problemData input variables and model input variables
+      // necessary workaround to have the variables in the occuring order
+      var inputvariables =
+        new HashSet<string>(Content.ProblemData.AllowedInputVariables.Union(Content.Model.VariablesUsedForPrediction));
+      var allowedInputVariables =
+        Content.ProblemData.Dataset.VariableNames.Where(v => inputvariables.Contains(v)).ToList();
+
+
+      var doubleVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<double>);
+      var doubleVariableValues = (IEnumerable<IList>)doubleVariables.Select(x => new List<double> { problemData.Dataset.GetDoubleValues(x, problemData.TrainingIndices).Median() });
+
+      var factorVariables = allowedInputVariables.Where(problemData.Dataset.VariableHasType<string>);
+      var factorVariableValues = (IEnumerable<IList>)factorVariables.Select(x => new List<string> {
+        problemData.Dataset.GetStringValues(x, problemData.TrainingIndices)
+        .GroupBy(val => val).OrderByDescending(g => g.Count()).First().Key // most frequent value
+      });
+
+      if (sharedFixedVariables != null)
+        sharedFixedVariables.ItemChanged -= SharedFixedVariables_ItemChanged;
+
+      sharedFixedVariables = new ModifiableDataset(doubleVariables.Concat(factorVariables), doubleVariableValues.Concat(factorVariableValues));
+
+
+      // create controls
+      partialDependencePlots.Clear();
+      densityCharts.Clear();
+      groupingPanels.Clear();
+      foreach (var variableName in doubleVariables) {
+        var plot = CreatePartialDependencePlot(variableName, sharedFixedVariables);
+        partialDependencePlots.Add(variableName, plot);
+
+        var densityChart = new DensityChart() {
+          Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right,
+          Margin = Padding.Empty,
+          Height = 12,
+          Visible = false,
+          Top = (int)(plot.Height * 0.1),
+        };
+        densityCharts.Add(variableName, densityChart);
+
+        plot.ZoomChanged += (o, e) => {
+          var pdp = (PartialDependencePlot)o;
+          var density = densityCharts[pdp.FreeVariable];
+          density.Visible = densityComboBox.SelectedIndex != 0 && !pdp.IsZoomed;
+          if (density.Visible)
+            UpdateDensityChart(density, pdp.FreeVariable);
+        };
+        plot.SizeChanged += (o, e) => {
+          var pdp = (PartialDependencePlot)o;
+          var density = densityCharts[pdp.FreeVariable];
+          density.Top = (int)(pdp.Height * 0.1);
+        };
+
+        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
+        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
+        plot.ChartPostPaint += OnPartialDependencePlotPostPaint;
+
+        var panel = new Panel() {
+          Dock = DockStyle.Fill,
+          Margin = Padding.Empty,
+          BackColor = Color.White
+        };
+
+        panel.Controls.Add(densityChart);
+        panel.Controls.Add(plot);
+        groupingPanels.Add(variableName, panel);
+      }
+      foreach (var variableName in factorVariables) {
+        var plot = CreateFactorPartialDependencePlot(variableName, sharedFixedVariables);
+        partialDependencePlots.Add(variableName, plot);
+
+        var densityChart = new DensityChart() {
+          Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Right,
+          Margin = Padding.Empty,
+          Height = 12,
+          Visible = false,
+          Top = (int)(plot.Height * 0.1),
+        };
+        densityCharts.Add(variableName, densityChart);
+        plot.ZoomChanged += (o, e) => {
+          var pdp = (FactorPartialDependencePlot)o;
+          var density = densityCharts[pdp.FreeVariable];
+          density.Visible = densityComboBox.SelectedIndex != 0 && !pdp.IsZoomed;
+          if (density.Visible)
+            UpdateDensityChart(density, pdp.FreeVariable);
+        };
+        plot.SizeChanged += (o, e) => {
+          var pdp = (FactorPartialDependencePlot)o;
+          var density = densityCharts[pdp.FreeVariable];
+          density.Top = (int)(pdp.Height * 0.1);
+        };
+
+        // Initially, the inner plot areas are not initialized for hidden charts (scollpanel, ...)
+        // This event handler listens for the paint event once (where everything is already initialized) to do some manual layouting.
+        plot.ChartPostPaint += OnFactorPartialDependencePlotPostPaint;
+
+        var panel = new Panel() {
+          Dock = DockStyle.Fill,
+          Margin = Padding.Empty,
+          BackColor = Color.White
+        };
+
+        panel.Controls.Add(densityChart);
+        panel.Controls.Add(plot);
+        groupingPanels.Add(variableName, panel);
+      }
+      // update variable list
+      variableListView.ItemChecked -= variableListView_ItemChecked;
+      variableListView.Items.Clear();
+      foreach (var variable in allowedInputVariables)
+        variableListView.Items.Add(key: variable, text: variable, imageIndex: 0);
+
+      foreach (var variable in Content.Model.VariablesUsedForPrediction)
+        variableListView.Items[variable].Checked = true;
+      variableListView.ItemChecked += variableListView_ItemChecked;
+
+      sharedFixedVariables.ItemChanged += SharedFixedVariables_ItemChanged;
+
+      RecalculateAndRelayoutCharts();
+    }
+
+    private void SharedFixedVariables_ItemChanged(object sender, EventArgs<int, int> e) {
+      double yValue = Content.Model.GetEstimatedValues(sharedFixedVariables, new[] { 0 }).Single();
+      string title = Content.ProblemData.TargetVariable + ": " + yValue.ToString("G5", CultureInfo.CurrentCulture);
+      foreach (var chart in partialDependencePlots.Values) {
+        if (!string.IsNullOrEmpty(chart.YAxisTitle)) { // only show title for first column in grid
+          chart.YAxisTitle = title;
+        }
+      }
+    }
+
+
+    private void OnPartialDependencePlotPostPaint(object o, EventArgs e) {
+      var plot = (PartialDependencePlot)o;
+      var density = densityCharts[plot.FreeVariable];
+
+      density.Width = plot.Width;
+
+      var gcPlotPosition = plot.InnerPlotPosition;
+      density.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width);
+      density.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width);
+      plot.UpdateTitlePosition();
+
+      // removed after succesful layouting due to performance reasons
+      if (gcPlotPosition.Width != 0)
+        plot.ChartPostPaint -= OnPartialDependencePlotPostPaint;
+    }
+
+    private void OnFactorPartialDependencePlotPostPaint(object o, EventArgs e) {
+      var plot = (FactorPartialDependencePlot)o;
+      var density = densityCharts[plot.FreeVariable];
+
+      density.Width = plot.Width;
+
+      var gcPlotPosition = plot.InnerPlotPosition;
+      density.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width);
+      density.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width);
+      plot.UpdateTitlePosition();
+
+      // removed after succesful layouting due to performance reasons
+      if (gcPlotPosition.Width != 0)
+        plot.ChartPostPaint -= OnFactorPartialDependencePlotPostPaint;
+    }
+
+    private async void RecalculateAndRelayoutCharts() {
+      foreach (var variable in VisibleVariables) {
+        var plot = partialDependencePlots[variable];
+        await plot.RecalculateAsync(false, false);
+      }
+      partialDependencePlotTableLayout.SuspendLayout();
+      SetupYAxis();
+      ReOrderControls();
+      SetStyles();
+      partialDependencePlotTableLayout.ResumeLayout();
+      partialDependencePlotTableLayout.Refresh();
+      foreach (var variable in VisibleVariables) {
+        DensityChart densityChart;
+        if (densityCharts.TryGetValue(variable, out densityChart)) {
+          UpdateDensityChart(densityChart, variable);
+        }
+      }
+    }
+    private PartialDependencePlot CreatePartialDependencePlot(string variableName, ModifiableDataset sharedFixedVariables) {
+      var plot = new PartialDependencePlot {
+        Dock = DockStyle.Fill,
+        Margin = Padding.Empty,
+        ShowLegend = false,
+        ShowCursor = true,
+        ShowConfigButton = false,
+        YAxisTicks = 5,
+      };
+      plot.VariableValueChanged += async (o, e) => {
+        var recalculations = VisiblePartialDependencePlots
+          .Except(new[] { (IPartialDependencePlot)o })
+          .Select(async chart => {
+            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
+          }).ToList();
+        await Task.WhenAll(recalculations);
+
+        if (recalculations.All(t => t.IsCompleted))
+          SetupYAxis();
+      };
+      plot.Configure(new[] { Content }, sharedFixedVariables, variableName, Points);
+      plot.SolutionAdded += partialDependencePlot_SolutionAdded;
+      plot.SolutionRemoved += partialDependencePlot_SolutionRemoved;
+      return plot;
+    }
+    private FactorPartialDependencePlot CreateFactorPartialDependencePlot(string variableName, ModifiableDataset sharedFixedVariables) {
+      var plot = new FactorPartialDependencePlot {
+        Dock = DockStyle.Fill,
+        Margin = Padding.Empty,
+        ShowLegend = false,
+        ShowCursor = true,
+        YAxisTicks = 5,
+      };
+      plot.VariableValueChanged += async (o, e) => {
+        var recalculations = VisiblePartialDependencePlots
+          .Except(new[] { (FactorPartialDependencePlot)o })
+          .Select(async chart => {
+            await chart.RecalculateAsync(updateOnFinish: false, resetYAxis: false);
+          }).ToList();
+        await Task.WhenAll(recalculations);
+
+        if (recalculations.All(t => t.IsCompleted))
+          SetupYAxis();
+      };
+      var variableValues = Content.ProblemData.Dataset.GetStringValues(variableName).Distinct().OrderBy(n => n).ToList();
+      plot.Configure(new[] { Content }, sharedFixedVariables, variableName, variableValues);
+      plot.SolutionAdded += partialDependencePlot_SolutionAdded;
+      plot.SolutionRemoved += partialDependencePlot_SolutionRemoved;
+      return plot;
+    }
+    private void SetupYAxis() {
+      double axisMin, axisMax;
+      if (automaticYAxisCheckBox.Checked) {
+        double min = double.MaxValue, max = double.MinValue;
+        foreach (var chart in VisiblePartialDependencePlots) {
+          if (chart.YMin < min) min = chart.YMin;
+          if (chart.YMax > max) max = chart.YMax;
+        }
+
+        double axisInterval;
+        ChartUtil.CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval);
+      } else {
+        axisMin = limitView.Content.Lower;
+        axisMax = limitView.Content.Upper;
+      }
+
+      foreach (var chart in VisiblePartialDependencePlots) {
+        chart.FixedYAxisMin = axisMin;
+        chart.FixedYAxisMax = axisMax;
+      }
+    }
+
+    // reorder chart controls so that they always appear in the same order as in the list view
+    // the table layout containing the controls should be suspended before calling this method
+    private void ReOrderControls() {
+      var tl = partialDependencePlotTableLayout;
+      tl.Controls.Clear();
+      int row = 0, column = 0;
+      double yValue = Content.Model.GetEstimatedValues(sharedFixedVariables, new[] { 0 }).Single();
+      string title = Content.ProblemData.TargetVariable + ": " + yValue.ToString("G5", CultureInfo.CurrentCulture);
+
+      foreach (var v in VisibleVariables) {
+        var chartsPanel = groupingPanels[v];
+        tl.Controls.Add(chartsPanel, column, row);
+
+        var chart = partialDependencePlots[v];
+        chart.YAxisTitle = column == 0 ? title : string.Empty;
+        column++;
+
+        if (column == MaxColumns) {
+          row++;
+          column = 0;
+        }
+      }
+    }
+
+    private void SetStyles() {
+      var tl = partialDependencePlotTableLayout;
+      tl.RowStyles.Clear();
+      tl.ColumnStyles.Clear();
+      int numVariables = VisibleVariables.Count();
+      if (numVariables == 0)
+        return;
+
+      // set column styles
+      tl.ColumnCount = Math.Min(numVariables, MaxColumns);
+      for (int c = 0; c < tl.ColumnCount; c++)
+        tl.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100.0f / tl.ColumnCount));
+
+      // set row styles
+      tl.RowCount = (int)Math.Ceiling((double)numVariables / tl.ColumnCount);
+      var columnWidth = tl.Width / tl.ColumnCount; // assume all columns have the same width
+      var rowHeight = (int)(0.8 * columnWidth);
+      for (int r = 0; r < tl.RowCount; r++)
+        tl.RowStyles.Add(new RowStyle(SizeType.Absolute, rowHeight));
+    }
+
+    private async void partialDependencePlot_SolutionAdded(object sender, EventArgs<IRegressionSolution> e) {
+      var solution = e.Value;
+      foreach (var chart in partialDependencePlots.Values) {
+        if (sender == chart) continue;
+        await chart.AddSolutionAsync(solution);
+      }
+    }
+
+    private async void partialDependencePlot_SolutionRemoved(object sender, EventArgs<IRegressionSolution> e) {
+      var solution = e.Value;
+      foreach (var chart in partialDependencePlots.Values) {
+        if (sender == chart) continue;
+        await chart.RemoveSolutionAsync(solution);
+      }
+    }
+
+    private async void variableListView_ItemChecked(object sender, ItemCheckedEventArgs e) {
+      var item = e.Item;
+      var variable = item.Text;
+      var plot = partialDependencePlots[variable];
+      var chartsPanel = groupingPanels[variable];
+      var tl = partialDependencePlotTableLayout;
+
+      tl.SuspendLayout();
+      if (item.Checked) {
+        tl.Controls.Add(chartsPanel);
+        await plot.RecalculateAsync(false, false);
+      } else {
+        tl.Controls.Remove(chartsPanel);
+      }
+
+      if (tl.Controls.Count > 0) {
+        SetupYAxis();
+        ReOrderControls();
+        SetStyles();
+      }
+      tl.ResumeLayout();
+      tl.Refresh();
+      densityComboBox_SelectedIndexChanged(this, EventArgs.Empty);
+    }
+
+    private void automaticYAxisCheckBox_CheckedChanged(object sender, EventArgs e) {
+      limitView.ReadOnly = automaticYAxisCheckBox.Checked;
+      SetupYAxis();
+      partialDependencePlotTableLayout.Refresh();
+      densityComboBox_SelectedIndexChanged(this, EventArgs.Empty); // necessary to realign the density plots
+    }
+
+    private void limit_ValueChanged(object sender, EventArgs e) {
+      if (automaticYAxisCheckBox.Checked)
+        return;
+      SetupYAxis();
+      partialDependencePlotTableLayout.Refresh();
+      densityComboBox_SelectedIndexChanged(this, EventArgs.Empty); // necessary to realign the density plots
+    }
+
+    private void densityComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      if (Content == null)
+        return;
+
+      int si = densityComboBox.SelectedIndex;
+      if (si == 0) {
+        foreach (var densityChart in densityCharts.Values)
+          densityChart.Visible = false;
+      } else {
+        var indices = GetDensityIndices(si).ToList();
+
+        foreach (var entry in densityCharts) {
+          var variableName = entry.Key;
+          var densityChart = entry.Value;
+          if (!VisibleVariables.Contains(variableName) || partialDependencePlots[variableName].IsZoomed)
+            continue;
+
+          UpdateDensityChart(densityChart, variableName, indices);
+        }
+      }
+    }
+    private IEnumerable<int> GetDensityIndices(int selectedIndex) {
+      var problemData = Content.ProblemData;
+      return
+        selectedIndex == 1 ? problemData.TrainingIndices :
+        selectedIndex == 2 ? problemData.TestIndices :
+        problemData.AllIndices;
+    }
+    private void UpdateDensityChart(DensityChart densityChart, string variable, IList<int> indices = null) {
+      if (densityComboBox.SelectedIndex == 0)
+        return;
+      if (indices == null) {
+        indices = GetDensityIndices(densityComboBox.SelectedIndex).ToList();
+      }
+      if (Content.ProblemData.Dataset.VariableHasType<double>(variable)) {
+        var data = Content.ProblemData.Dataset.GetDoubleValues(variable, indices).ToList();
+        var plot = partialDependencePlots[variable] as PartialDependencePlot;
+        if (plot != null) {
+          var min = plot.FixedXAxisMin;
+          var max = plot.FixedXAxisMax;
+          var buckets = plot.DrawingSteps;
+          if (min.HasValue && max.HasValue) {
+            densityChart.UpdateChart(data, min.Value, max.Value, buckets);
+            densityChart.Width = plot.Width;
+
+            var gcPlotPosition = plot.InnerPlotPosition;
+            densityChart.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width);
+            densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width);
+
+            densityChart.Visible = true;
+          }
+          plot.UpdateTitlePosition();
+        }
+      } else if (Content.ProblemData.Dataset.VariableHasType<string>(variable)) {
+        var data = Content.ProblemData.Dataset.GetStringValues(variable).ToList();
+        var plot = partialDependencePlots[variable] as FactorPartialDependencePlot;
+        if (plot != null) {
+          densityChart.UpdateChart(data);
+          densityChart.Width = plot.Width;
+
+          var gcPlotPosition = plot.InnerPlotPosition;
+          densityChart.Left = (int)(gcPlotPosition.X / 100.0 * plot.Width);
+          densityChart.Width = (int)(gcPlotPosition.Width / 100.0 * plot.Width);
+
+          densityChart.Visible = true;
+
+          plot.UpdateTitlePosition();
+        }
+      }
+    }
+
+    private void columnsNumericUpDown_ValueChanged(object sender, EventArgs e) {
+      MaxColumns = (int)columnsNumericUpDown.Value;
+      int columns = Math.Min(VisibleVariables.Count(), MaxColumns);
+      if (columns > 0) {
+        var tl = partialDependencePlotTableLayout;
+        MaxColumns = columns;
+        tl.SuspendLayout();
+        ReOrderControls();
+        SetStyles();
+        tl.ResumeLayout();
+        tl.Refresh();
+        densityComboBox_SelectedIndexChanged(this, EventArgs.Empty);
+      }
+    }
+
+    private async void solution_ModelChanged(object sender, EventArgs e) {
+      foreach (var variable in VisibleVariables) {
+        var pdp = partialDependencePlots[variable];
+        var densityChart = densityCharts[variable];
+        // recalculate and refresh
+        await pdp.RecalculateAsync(false, false);
+        pdp.Refresh();
+        UpdateDensityChart(densityChart, variable);
+      }
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.Designer.cs	(revision 15281)
@@ -0,0 +1,79 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionResidualAnalysisView {
+    /// <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.bubbleChartView = new HeuristicLab.Optimization.Views.RunCollectionBubbleChartView();
+      this.SuspendLayout();
+      // 
+      // bubbleChartView
+      // 
+      this.bubbleChartView.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.bubbleChartView.BackColor = System.Drawing.SystemColors.Window;
+      this.bubbleChartView.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.bubbleChartView.Caption = "Bubble Chart";
+      this.bubbleChartView.Content = null;
+      this.bubbleChartView.Location = new System.Drawing.Point(3, 3);
+      this.bubbleChartView.Name = "bubbleChartView";
+      this.bubbleChartView.ReadOnly = false;
+      this.bubbleChartView.Size = new System.Drawing.Size(855, 523);
+      this.bubbleChartView.TabIndex = 0;
+      // 
+      // RegressionSolutionResidualAnalysisView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.bubbleChartView);
+      this.Name = "RegressionSolutionResidualAnalysisView";
+      this.Size = new System.Drawing.Size(861, 529);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private Optimization.Views.RunCollectionBubbleChartView bubbleChartView;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualAnalysisView.cs	(revision 15281)
@@ -0,0 +1,154 @@
+﻿#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.Drawing;
+using System.Linq;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Residual Analysis")]
+  [Content(typeof(IRegressionSolution))]
+  public sealed partial class RegressionSolutionResidualAnalysisView : DataAnalysisSolutionEvaluationView {
+
+    // names should be relatively save to prevent collisions with variable names in the dataset
+    private const string TargetLabel = "> Target";
+    private const string PredictionLabel = "> Prediction";
+    private const string ResidualLabel = "> Residual";
+    private const string AbsResidualLabel = "> Residual (abs.)";
+    private const string RelativeErrorLabel = "> Relative Error";
+    private const string AbsRelativeErrorLabel = "> Relative Error (abs.)";
+    private const string PartitionLabel = "> Partition";
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionSolutionResidualAnalysisView() : base() {
+      InitializeComponent();
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        bubbleChartView.Content = null;
+      } else {
+        UpdateBubbleChart();
+      }
+    }
+
+    private void UpdateBubbleChart() {
+      if (Content == null) return;
+      var selectedXAxis = bubbleChartView.SelectedXAxis;
+      var selectedYAxis = bubbleChartView.SelectedYAxis;
+
+      var problemData = Content.ProblemData;
+      var ds = problemData.Dataset;
+      var runs = new RunCollection();
+      // determine relevant variables (at least two different values)
+      var doubleVars = ds.DoubleVariables.Where(vn => ds.GetDoubleValues(vn).Max() > ds.GetDoubleValues(vn).Min()).ToArray();
+      var stringVars = ds.StringVariables.Where(vn => ds.GetStringValues(vn).Distinct().Skip(1).Any()).ToArray();
+      var dateTimeVars = ds.DateTimeVariables.Where(vn => ds.GetDateTimeValues(vn).Distinct().Skip(1).Any()).ToArray();
+
+      // produce training and test values separately as they might overlap (e.g. for ensembles)
+      var predictedValuesTrain = Content.EstimatedTrainingValues.ToArray();
+      int j = 0; // idx for predictedValues array
+      foreach (var i in problemData.TrainingIndices) {
+        var run = CreateRunForIdx(i, problemData, doubleVars, stringVars, dateTimeVars);
+        var targetValue = ds.GetDoubleValue(problemData.TargetVariable, i);
+        AddErrors(run, predictedValuesTrain[j++], targetValue);
+        run.Results.Add(PartitionLabel, new StringValue("Training"));
+        run.Color = Color.Gold;
+        runs.Add(run);
+      }
+      var predictedValuesTest = Content.EstimatedTestValues.ToArray();
+      j = 0;
+      foreach (var i in problemData.TestIndices) {
+        var run = CreateRunForIdx(i, problemData, doubleVars, stringVars, dateTimeVars);
+        var targetValue = ds.GetDoubleValue(problemData.TargetVariable, i);
+        AddErrors(run, predictedValuesTest[j++], targetValue);
+        run.Results.Add(PartitionLabel, new StringValue("Test"));
+        run.Color = Color.Red;
+        runs.Add(run);
+      }
+      if (string.IsNullOrEmpty(selectedXAxis))
+        selectedXAxis = "Index";
+      if (string.IsNullOrEmpty(selectedYAxis))
+        selectedYAxis = "Residual";
+
+      bubbleChartView.Content = runs;
+      bubbleChartView.SelectedXAxis = selectedXAxis;
+      bubbleChartView.SelectedYAxis = selectedYAxis;
+    }
+
+    private void AddErrors(IRun run, double pred, double target) {
+      var residual = target - pred;
+      var relError = residual / target;
+      run.Results.Add(TargetLabel, new DoubleValue(target));
+      run.Results.Add(PredictionLabel, new DoubleValue(pred));
+      run.Results.Add(ResidualLabel, new DoubleValue(residual));
+      run.Results.Add(AbsResidualLabel, new DoubleValue(Math.Abs(residual)));
+      run.Results.Add(RelativeErrorLabel, new DoubleValue(relError));
+      run.Results.Add(AbsRelativeErrorLabel, new DoubleValue(Math.Abs(relError)));
+    }
+
+    private IRun CreateRunForIdx(int i, IRegressionProblemData problemData, IEnumerable<string> doubleVars, IEnumerable<string> stringVars, IEnumerable<string> dateTimeVars) {
+      var ds = problemData.Dataset;
+      var run = new Run();
+      foreach (var variableName in doubleVars) {
+        run.Results.Add(variableName, new DoubleValue(ds.GetDoubleValue(variableName, i)));
+      }
+      foreach (var variableName in stringVars) {
+        run.Results.Add(variableName, new StringValue(ds.GetStringValue(variableName, i)));
+      }
+      foreach (var variableName in dateTimeVars) {
+        run.Results.Add(variableName, new DateTimeValue(ds.GetDateTimeValue(variableName, i)));
+      }
+      return run;
+    }
+    #endregion
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.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.
@@ -96,4 +96,5 @@
 
         ChartArea chartArea = chart.ChartAreas[0];
+        chartArea.AxisX.Title = string.Format("Residuals ({0})", Content.ProblemData.TargetVariable);
         chartArea.AxisX.Minimum = -roundedMax - intervalWidth;
         chartArea.AxisX.Maximum = roundedMax + intervalWidth;
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.Designer.cs	(revision 15281)
@@ -0,0 +1,52 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionResidualsLineChartView {
+    /// <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() {
+
+    }
+
+    #endregion
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualsLineChartView.cs	(revision 15281)
@@ -0,0 +1,95 @@
+﻿#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.Linq;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Residuals Line Chart")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionResidualsLineChartView : RegressionSolutionLineChartViewBase, IDataAnalysisSolutionEvaluationView {
+
+    public RegressionSolutionResidualsLineChartView() : base() {
+      InitializeComponent();
+    }
+
+    protected void CalcResiduals(int[] idx, double[] x) {
+      var problemData = Content.ProblemData;
+      var target = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, idx).ToArray();
+      for (int i = 0; i < idx.Length; i++) {
+        x[i] = target[i] - x[i];
+      }
+    }
+
+    protected override void GetTrainingSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TrainingIndices.ToArray();
+      y = Content.EstimatedTrainingValues.ToArray();
+      CalcResiduals(idx, y);
+    }
+
+    protected override void GetTestSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TestIndices.ToArray();
+      y = Content.EstimatedTestValues.ToArray();
+      CalcResiduals(idx, y);
+    }
+
+    protected override void GetAllValuesSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.AllIndices.ToArray();
+      y = Content.EstimatedValues.ToArray();
+      CalcResiduals(idx, y);
+    }
+
+    protected override void RedrawChart() {
+      base.RedrawChart();
+      UpdateSeriesStyle();
+    }
+
+    private void UpdateSeriesStyle() {
+      if (Content == null) return;
+
+      if (InvokeRequired) {
+        Invoke((Action)UpdateSeriesStyle);
+        return;
+      }
+
+      double[] res;
+      int[] idx;
+      GetTrainingSeries(out idx, out res);
+      chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].YAxisType = AxisType.Secondary;
+      chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.RangeColumn;
+      chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(idx, res.Select(_ => 0.0).ToArray(), res);
+
+      GetTestSeries(out idx, out res);
+      chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].YAxisType = AxisType.Secondary;
+      chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.RangeColumn;
+      chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(idx, res.Select(_ => 0.0).ToArray(), res);
+
+      GetAllValuesSeries(out idx, out res);
+      chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].YAxisType = AxisType.Secondary;
+      chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.RangeColumn;
+      chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(idx, res.Select(_ => 0.0).ToArray(), res);
+      ToggleSeriesData(chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]); // don't show by default
+    }
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.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.
@@ -76,14 +76,14 @@
       //configure axis 
       this.chart.CustomizeAllChartAreas();
-      this.chart.ChartAreas[0].AxisX.Title = "Estimated Values";
+      this.chart.ChartAreas[0].AxisY.Title = "Estimated Values";
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 1;
+      this.chart.ChartAreas[0].CursorY.Interval = 1;
+
+      this.chart.ChartAreas[0].AxisX.Title = "Target Values";
       this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
       this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].CursorX.Interval = 1;
-      this.chart.ChartAreas[0].CursorY.Interval = 1;
-
-      this.chart.ChartAreas[0].AxisY.Title = "Target Values";
-      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
-      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
-      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
     }
 
@@ -158,24 +158,25 @@
         var dataset = Content.ProblemData.Dataset;
         if (this.chart.Series[ALL_SERIES].Points.Count > 0)
-          this.chart.Series[ALL_SERIES].Points.DataBindXY(Content.EstimatedValues.ToArray(), "",
-            dataset.GetDoubleValues(targetVariableName).ToArray(), "");
+          this.chart.Series[ALL_SERIES].Points.DataBindXY(dataset.GetDoubleValues(targetVariableName).ToArray(), "",
+            Content.EstimatedValues.ToArray(), "");
         if (this.chart.Series[TRAINING_SERIES].Points.Count > 0)
-          this.chart.Series[TRAINING_SERIES].Points.DataBindXY(Content.EstimatedTrainingValues.ToArray(), "",
-            dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray(), "");
+          this.chart.Series[TRAINING_SERIES].Points.DataBindXY(dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray(), "",
+            Content.EstimatedTrainingValues.ToArray(), "");
         if (this.chart.Series[TEST_SERIES].Points.Count > 0)
-          this.chart.Series[TEST_SERIES].Points.DataBindXY(Content.EstimatedTestValues.ToArray(), "",
-           dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray(), "");
-
+          this.chart.Series[TEST_SERIES].Points.DataBindXY(dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray(), "",
+            Content.EstimatedTestValues.ToArray(), "");
         double max = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Max();
         double min = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Min();
 
         double axisMin, axisMax, axisInterval;
-        ChartUtil.CalculateAxisInterval(min, max, 5, out axisMin, out axisMax, out axisInterval);
+        ChartUtil.CalculateOptimalAxisInterval(min, max, out axisMin, out axisMax, out axisInterval);
+        this.chart.ChartAreas[0].AxisY.Title = "Estimated " + targetVariableName;
+        this.chart.ChartAreas[0].AxisY.Maximum = axisMax;
+        this.chart.ChartAreas[0].AxisY.Minimum = axisMin;
+        this.chart.ChartAreas[0].AxisY.Interval = axisInterval;
+        this.chart.ChartAreas[0].AxisX.Title = targetVariableName;
         this.chart.ChartAreas[0].AxisX.Maximum = axisMax;
         this.chart.ChartAreas[0].AxisX.Minimum = axisMin;
         this.chart.ChartAreas[0].AxisX.Interval = axisInterval;
-        this.chart.ChartAreas[0].AxisY.Maximum = axisMax;
-        this.chart.ChartAreas[0].AxisY.Minimum = axisMin;
-        this.chart.ChartAreas[0].AxisY.Interval = axisInterval;
 
         UpdateCursorInterval();
@@ -214,5 +215,5 @@
         }
         if (predictedValues.Length == targetValues.Length)
-          series.Points.DataBindXY(predictedValues, "", targetValues, "");
+          series.Points.DataBindXY(targetValues, "", predictedValues, "");
         this.chart.Legends[series.Legend].ForeColor = Color.Black;
         UpdateCursorInterval();
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.Designer.cs	(revision 15281)
@@ -0,0 +1,163 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionVariableImpactsView {
+    /// <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.variableImactsArrayView = new HeuristicLab.Data.Views.StringConvertibleArrayView();
+      this.dataPartitionComboBox = new System.Windows.Forms.ComboBox();
+      this.dataPartitionLabel = new System.Windows.Forms.Label();
+      this.numericVarReplacementLabel = new System.Windows.Forms.Label();
+      this.replacementComboBox = new System.Windows.Forms.ComboBox();
+      this.factorVarReplacementLabel = new System.Windows.Forms.Label();
+      this.factorVarReplComboBox = new System.Windows.Forms.ComboBox();
+      this.SuspendLayout();
+      // 
+      // variableImactsArrayView
+      // 
+      this.variableImactsArrayView.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.variableImactsArrayView.Caption = "StringConvertibleArray View";
+      this.variableImactsArrayView.Content = null;
+      this.variableImactsArrayView.Location = new System.Drawing.Point(3, 84);
+      this.variableImactsArrayView.Name = "variableImactsArrayView";
+      this.variableImactsArrayView.ReadOnly = true;
+      this.variableImactsArrayView.Size = new System.Drawing.Size(363, 278);
+      this.variableImactsArrayView.TabIndex = 2;
+      // 
+      // dataPartitionComboBox
+      // 
+      this.dataPartitionComboBox.FormattingEnabled = true;
+      this.dataPartitionComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Training,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.Test,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.DataPartitionEnum.All});
+      this.dataPartitionComboBox.Location = new System.Drawing.Point(197, 3);
+      this.dataPartitionComboBox.Name = "dataPartitionComboBox";
+      this.dataPartitionComboBox.Size = new System.Drawing.Size(121, 21);
+      this.dataPartitionComboBox.TabIndex = 1;
+      this.dataPartitionComboBox.SelectedIndexChanged += new System.EventHandler(this.dataPartitionComboBox_SelectedIndexChanged);
+      // 
+      // dataPartitionLabel
+      // 
+      this.dataPartitionLabel.AutoSize = true;
+      this.dataPartitionLabel.Location = new System.Drawing.Point(3, 6);
+      this.dataPartitionLabel.Name = "dataPartitionLabel";
+      this.dataPartitionLabel.Size = new System.Drawing.Size(73, 13);
+      this.dataPartitionLabel.TabIndex = 0;
+      this.dataPartitionLabel.Text = "Data partition:";
+      // 
+      // numericVarReplacementLabel
+      // 
+      this.numericVarReplacementLabel.AutoSize = true;
+      this.numericVarReplacementLabel.Location = new System.Drawing.Point(3, 33);
+      this.numericVarReplacementLabel.Name = "numericVarReplacementLabel";
+      this.numericVarReplacementLabel.Size = new System.Drawing.Size(173, 13);
+      this.numericVarReplacementLabel.TabIndex = 2;
+      this.numericVarReplacementLabel.Text = "Replacement for numeric variables:";
+      // 
+      // replacementComboBox
+      // 
+      this.replacementComboBox.FormattingEnabled = true;
+      this.replacementComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum.Median,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum.Average,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum.Noise,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum.Shuffle});
+      this.replacementComboBox.Location = new System.Drawing.Point(197, 30);
+      this.replacementComboBox.Name = "replacementComboBox";
+      this.replacementComboBox.Size = new System.Drawing.Size(121, 21);
+      this.replacementComboBox.TabIndex = 3;
+      this.replacementComboBox.SelectedIndexChanged += new System.EventHandler(this.replacementComboBox_SelectedIndexChanged);
+      // 
+      // factorVarReplacementLabel
+      // 
+      this.factorVarReplacementLabel.AutoSize = true;
+      this.factorVarReplacementLabel.Location = new System.Drawing.Point(3, 60);
+      this.factorVarReplacementLabel.Name = "factorVarReplacementLabel";
+      this.factorVarReplacementLabel.Size = new System.Drawing.Size(188, 13);
+      this.factorVarReplacementLabel.TabIndex = 0;
+      this.factorVarReplacementLabel.Text = "Replacement for categorical variables:";
+      // 
+      // factorVarReplComboBox
+      // 
+      this.factorVarReplComboBox.FormattingEnabled = true;
+      this.factorVarReplComboBox.Items.AddRange(new object[] {
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Best,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Mode,
+            HeuristicLab.Problems.DataAnalysis.RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum.Shuffle});
+      this.factorVarReplComboBox.Location = new System.Drawing.Point(197, 57);
+      this.factorVarReplComboBox.Name = "factorVarReplComboBox";
+      this.factorVarReplComboBox.Size = new System.Drawing.Size(121, 21);
+      this.factorVarReplComboBox.TabIndex = 1;
+      this.factorVarReplComboBox.SelectedIndexChanged += new System.EventHandler(this.replacementComboBox_SelectedIndexChanged);
+      // 
+      // RegressionSolutionVariableImpactsView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.factorVarReplComboBox);
+      this.Controls.Add(this.factorVarReplacementLabel);
+      this.Controls.Add(this.replacementComboBox);
+      this.Controls.Add(this.numericVarReplacementLabel);
+      this.Controls.Add(this.dataPartitionLabel);
+      this.Controls.Add(this.dataPartitionComboBox);
+      this.Controls.Add(this.variableImactsArrayView);
+      this.Name = "RegressionSolutionVariableImpactsView";
+      this.Size = new System.Drawing.Size(369, 365);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private Data.Views.StringConvertibleArrayView variableImactsArrayView;
+    private System.Windows.Forms.ComboBox dataPartitionComboBox;
+    private System.Windows.Forms.Label dataPartitionLabel;
+    private System.Windows.Forms.Label numericVarReplacementLabel;
+    private System.Windows.Forms.ComboBox replacementComboBox;
+    private System.Windows.Forms.Label factorVarReplacementLabel;
+    private System.Windows.Forms.ComboBox factorVarReplComboBox;
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionVariableImpactsView.cs	(revision 15281)
@@ -0,0 +1,117 @@
+﻿#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.Linq;
+using System.Threading.Tasks;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Regression;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Variable Impacts")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionVariableImpactsView : DataAnalysisSolutionEvaluationView {
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set {
+        base.Content = value;
+      }
+    }
+
+    public RegressionSolutionVariableImpactsView()
+      : base() {
+      InitializeComponent();
+      this.dataPartitionComboBox.SelectedIndex = 0;
+      this.replacementComboBox.SelectedIndex = 0;
+      this.factorVarReplComboBox.SelectedIndex = 0;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        variableImactsArrayView.Content = null;
+      } else {
+        UpdateVariableImpacts();
+      }
+    }
+
+    private void UpdateVariableImpacts() {
+      if (Content == null || replacementComboBox.SelectedIndex < 0
+        || factorVarReplComboBox.SelectedIndex < 0
+        || dataPartitionComboBox.SelectedIndex < 0) return;
+      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
+      variableImactsArrayView.Caption = Content.Name + " Variable Impacts";
+      var replMethod =
+         (RegressionSolutionVariableImpactsCalculator.ReplacementMethodEnum)
+           replacementComboBox.Items[replacementComboBox.SelectedIndex];
+      var factorReplMethod =
+        (RegressionSolutionVariableImpactsCalculator.FactorReplacementMethodEnum)
+          factorVarReplComboBox.Items[factorVarReplComboBox.SelectedIndex];
+      var dataPartition =
+        (RegressionSolutionVariableImpactsCalculator.DataPartitionEnum)dataPartitionComboBox.SelectedItem;
+
+      Task.Factory.StartNew(() => {
+        try {
+          mainForm.AddOperationProgressToView(this, "Calculating variable impacts for " + Content.Name);
+
+          var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content, dataPartition, replMethod, factorReplMethod);
+          var impactArray = new DoubleArray(impacts.Select(i => i.Item2).ToArray());
+          impactArray.ElementNames = impacts.Select(i => i.Item1);
+          variableImactsArrayView.Content = (DoubleArray)impactArray.AsReadOnly();
+        } finally {
+          mainForm.RemoveOperationProgressFromView(this);
+        }
+      });
+    }
+
+    #endregion
+
+    private void dataPartitionComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateVariableImpacts();
+    }
+
+    private void replacementComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateVariableImpacts();
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.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.
@@ -29,5 +29,4 @@
 using HeuristicLab.MainForm;
 using HeuristicLab.Optimization;
-using HeuristicLab.Optimization.Views;
 using HeuristicLab.Persistence.Default.Xml;
 using HeuristicLab.PluginInfrastructure;
@@ -97,5 +96,5 @@
     }
 
-    protected override void itemsListView_DoubleClick(object sender, EventArgs e) {
+    protected sealed override void itemsListView_DoubleClick(object sender, EventArgs e) {
       if (itemsListView.SelectedItems.Count != 1) return;
 
@@ -103,6 +102,7 @@
       Type viewType = itemsListView.SelectedItems[0].Tag as Type;
       if (result != null) {
-        IContentView view = MainFormManager.MainForm.ShowContent(result, typeof(ResultView));
+        IContentView view = MainFormManager.MainForm.ShowContent(result.Value);
         if (view != null) {
+          view.Caption = result.Name;
           view.ReadOnly = ReadOnly;
           view.Locked = Locked;
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.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.
@@ -46,5 +46,4 @@
     /// </summary>
     private void InitializeComponent() {
-      this.btnImpactCalculation = new System.Windows.Forms.Button();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
       this.splitContainer.Panel1.SuspendLayout();
@@ -54,26 +53,4 @@
       this.detailsGroupBox.SuspendLayout();
       this.SuspendLayout();
-      // 
-      // btnImpactCalculation
-      // 
-      this.btnImpactCalculation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)));
-      this.btnImpactCalculation.Image = HeuristicLab.Common.Resources.VSImageLibrary.Zoom;
-      this.btnImpactCalculation.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
-      this.btnImpactCalculation.Name = "btnImpactCalculation";
-      this.btnImpactCalculation.TabIndex = 6;
-      this.btnImpactCalculation.Size = new System.Drawing.Size(110, 24);
-      this.btnImpactCalculation.Text = "Variable Impacts";
-      this.btnImpactCalculation.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
-      this.btnImpactCalculation.UseVisualStyleBackColor = true;
-      this.btnImpactCalculation.Click += new System.EventHandler(this.btnImpactCalculation_Click);
-      this.toolTip.SetToolTip(this.btnImpactCalculation, "Calculate impacts");
-      // 
-      // flowLayoutPanel
-      // 
-      this.flowLayoutPanel.Controls.Add(this.btnImpactCalculation);
-      // 
-      // splitContainer
-      // 
-      // 
       // itemsGroupBox
       // 
@@ -104,6 +81,4 @@
 
     #endregion
-
-    protected System.Windows.Forms.Button btnImpactCalculation;
   }
 }
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.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.
@@ -20,16 +20,10 @@
 #endregion
 
-using System;
-using System.Linq;
-using System.Threading.Tasks;
 using System.Windows.Forms;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Data.Views;
 using HeuristicLab.MainForm;
-using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  [View("RegressionSolution View")]
+  [View("Solution View")]
   [Content(typeof(RegressionSolutionBase), false)]
   public partial class RegressionSolutionView : DataAnalysisSolutionView {
@@ -41,30 +35,4 @@
       get { return (RegressionSolutionBase)base.Content; }
       set { base.Content = value; }
-    }
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      btnImpactCalculation.Enabled = Content != null && !Locked;
-    }
-
-    protected virtual void btnImpactCalculation_Click(object sender, EventArgs e) {
-      var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
-      var view = new StringConvertibleArrayView();
-      view.Caption = Content.Name + " Variable Impacts";
-      view.Show();
-
-      Task.Factory.StartNew(() => {
-        try {
-          mainForm.AddOperationProgressToView(view, "Calculating variable impacts for " + Content.Name);
-
-          var impacts = RegressionSolutionVariableImpactsCalculator.CalculateImpacts(Content);
-          var impactArray = new DoubleArray(impacts.Select(i => i.Item2).ToArray());
-          impactArray.ElementNames = impacts.Select(i => i.Item1);
-          view.Content = (DoubleArray)impactArray.AsReadOnly();
-        }
-        finally {
-          mainForm.RemoveOperationProgressFromView(view);
-        }
-      });
     }
 
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.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.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.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.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.Designer.cs	(revision 15281)
@@ -0,0 +1,52 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisLineChartView {
+    /// <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() {
+
+    }
+
+    #endregion
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisLineChartView.cs	(revision 15281)
@@ -0,0 +1,59 @@
+﻿#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.Linq;
+using HeuristicLab.MainForm;
+
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Line Chart (prognosis)")]
+  [Content(typeof(ITimeSeriesPrognosisSolution))]
+  public partial class TimeSeriesPrognosisLineChartView : RegressionSolutionLineChartView {
+
+
+    public new ITimeSeriesPrognosisSolution Content {
+      get { return (ITimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public TimeSeriesPrognosisLineChartView()
+      : base() {
+      InitializeComponent();
+
+    }
+
+    protected override void GetTrainingSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TrainingIndices.ToArray();
+      y = Content.EstimatedTrainingValues.ToArray();
+    }
+
+    protected override void GetTestSeries(out int[] idx, out double[] y) {
+      // treat the whole test partition as prognosis horizon
+      idx = Content.ProblemData.TestIndices.ToArray();
+      y = Content.PrognosedTestValues.ToArray();
+    }
+
+    protected override void GetAllValuesSeries(out int[] idx, out double[] y) {
+      // not supported
+      idx = new int[0];
+      y = new double[0];
+    }
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.Designer.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.Designer.cs	(revision 15281)
@@ -0,0 +1,52 @@
+﻿#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.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisResidualsLineChartView {
+    /// <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() {
+
+    }
+
+    #endregion
+
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.cs	(revision 15281)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResidualsLineChartView.cs	(revision 15281)
@@ -0,0 +1,55 @@
+﻿#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.Linq;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Residuals Line Chart (prognosis)")]
+  [Content(typeof(ITimeSeriesPrognosisSolution))]
+  public partial class TimeSeriesPrognosisResidualsLineChartView : RegressionSolutionResidualsLineChartView, IDataAnalysisSolutionEvaluationView {
+
+    public new ITimeSeriesPrognosisSolution Content {
+      get { return (ITimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public TimeSeriesPrognosisResidualsLineChartView()
+      : base() {
+      InitializeComponent();
+    }                                                                                                      
+
+    protected override void GetTestSeries(out int[] idx, out double[] y) {
+      idx = Content.ProblemData.TestIndices.ToArray();
+      y = Content.PrognosedTestValues.ToArray();
+      CalcResiduals(idx, y);
+    }
+
+    protected override void GetAllValuesSeries(out int[] idx, out double[] y) {
+      // not supported
+      idx = new int[0];
+      y = new double[0];
+    }                                                                                     
+  }
+}
Index: branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.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.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.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.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.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.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 15280)
+++ branches/Async/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.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.
