Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 6618)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 6647)
@@ -19,46 +19,47 @@
  */
 #endregion
-
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
-  #region License Information
-  /* HeuristicLab
- * Copyright (C) 2002-2011 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.Core;
-  using HeuristicLab.Core.Views;
-  using HeuristicLab.MainForm;
-  using HeuristicLab.MainForm.WindowsForms;
+  [View("Ensemble Solutions")]
+  [Content(typeof(RegressionEnsembleSolution), false)]
+  internal sealed partial class RegressionEnsembleSolutionModelView : DataAnalysisSolutionEvaluationView {
+    private ModelsView view;
 
-  [View("Ensemble Solutions")]
-  [Content(typeof(IItemCollection<IRegressionSolution>), false)]
-  internal sealed partial class RegressionEnsembleSolutionModelView : ItemCollectionView<IRegressionSolution> {
     public RegressionEnsembleSolutionModelView() {
       InitializeComponent();
+      view = new ModelsView();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
     }
 
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-      addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
-      removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
-      itemsListView.Enabled = Content != null;
-      detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+    public new RegressionEnsembleSolution Content {
+      get { return (RegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null)
+        view.Content = Content.RegressionSolutions;
+      else
+        view.Content = null;
+    }
+
+    public override System.Drawing.Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Properties; }
+    }
+
+    private class ModelsView : ItemCollectionView<IRegressionSolution> {
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
+        removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
+        itemsListView.Enabled = Content != null;
+        detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+      }
     }
   }
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 6647)
@@ -0,0 +1,92 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionErrorCharacteristicsCurveView {
+    /// <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.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.label1 = new System.Windows.Forms.Label();
+      this.cmbSamples = new System.Windows.Forms.ComboBox();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(6, 28);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(366, 202);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(47, 13);
+      this.label1.TabIndex = 4;
+      this.label1.Text = "Samples";
+      // 
+      // cmbSamples
+      // 
+      this.cmbSamples.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbSamples.FormattingEnabled = true;
+      this.cmbSamples.Location = new System.Drawing.Point(56, 3);
+      this.cmbSamples.Name = "cmbSamples";
+      this.cmbSamples.Size = new System.Drawing.Size(121, 21);
+      this.cmbSamples.TabIndex = 3;
+      this.cmbSamples.SelectedIndexChanged += new System.EventHandler(this.cmbSamples_SelectedIndexChanged);
+      // 
+      // RegressionSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.cmbSamples);
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionErrorCharacteristicsCurveView";
+      this.Size = new System.Drawing.Size(366, 230);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    protected System.Windows.Forms.Label label1;
+    protected System.Windows.Forms.ComboBox cmbSamples;
+  }
+}
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 6647)
@@ -0,0 +1,227 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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 System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionErrorCharacteristicsCurveView : DataAnalysisSolutionEvaluationView {
+    protected const string TrainingSamples = "Training";
+    protected const string TestSamples = "Test";
+    protected const string AllSamples = "All Samples";
+
+    public RegressionSolutionErrorCharacteristicsCurveView()
+      : base() {
+      InitializeComponent();
+
+      cmbSamples.Items.Add(TrainingSamples);
+      cmbSamples.Items.Add(TestSamples);
+      cmbSamples.Items.Add(AllSamples);
+
+      cmbSamples.SelectedIndex = 0;
+
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].AxisX.Title = "Absolute Error";
+      chart.ChartAreas[0].AxisX.Minimum = 0.0;
+      chart.ChartAreas[0].AxisX.Maximum = 1.0;
+      chart.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
+      chart.ChartAreas[0].CursorX.Interval = 0.01;
+
+      chart.ChartAreas[0].AxisY.Title = "Number of Samples";
+      chart.ChartAreas[0].AxisY.Minimum = 0.0;
+      chart.ChartAreas[0].AxisY.Maximum = 1.0;
+      chart.ChartAreas[0].AxisY.MajorGrid.Interval = 0.2;
+      chart.ChartAreas[0].CursorY.Interval = 0.01;
+    }
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+    public IRegressionProblemData ProblemData {
+      get {
+        if (Content == null) return null;
+        return Content.ProblemData;
+      }
+    }
+
+    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_ModelChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ModelChanged, sender, e);
+      else UpdateChart();
+    }
+    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ProblemDataChanged, sender, e);
+      else {
+        UpdateChart();
+      }
+    }
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    protected virtual void UpdateChart() {
+      chart.Series.Clear();
+      chart.Annotations.Clear();
+      if (Content == null) return;
+
+      var originalValues = GetOriginalValues();
+      var meanModelEstimatedValues = GetMeanModelEstimatedValues(originalValues);
+      var meanModelResiduals = GetResiduals(originalValues, meanModelEstimatedValues);
+
+      meanModelResiduals.Sort();
+      chart.ChartAreas[0].AxisX.Maximum = Math.Ceiling(meanModelResiduals.Last());
+      chart.ChartAreas[0].CursorX.Interval = meanModelResiduals.First() / 100;
+
+      Series meanModelSeries = new Series("Mean Model");
+      meanModelSeries.ChartType = SeriesChartType.FastLine;
+      UpdateSeries(meanModelResiduals, meanModelSeries);
+      meanModelSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(meanModelSeries);
+      chart.Series.Add(meanModelSeries);
+
+      AddRegressionSolution(Content);
+    }
+
+    protected void AddRegressionSolution(IRegressionSolution solution) {
+      if (chart.Series.Any(s => s.Name == solution.Name)) return;
+
+      Series solutionSeries = new Series(solution.Name);
+      solutionSeries.Tag = solution;
+      solutionSeries.ChartType = SeriesChartType.FastLine;
+      var estimatedValues = GetResiduals(GetOriginalValues(), GetEstimatedValues(solution));
+      UpdateSeries(estimatedValues, solutionSeries);
+      solutionSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(solutionSeries);
+      chart.Series.Add(solutionSeries);
+    }
+
+    protected void UpdateSeries(List<double> residuals, Series series) {
+      series.Points.Clear();
+      residuals.Sort();
+
+      series.Points.AddXY(0, 0);
+      for (int i = 0; i < residuals.Count; i++) {
+        var point = new DataPoint();
+        if (residuals[i] > chart.ChartAreas[0].AxisX.Maximum) {
+          point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+          point.YValues[0] = ((double)i - 1) / residuals.Count;
+          point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+          series.Points.Add(point);
+          break;
+        }
+
+        point.XValue = residuals[i];
+        point.YValues[0] = ((double)i) / residuals.Count;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+
+      if (series.Points.Last().XValue < chart.ChartAreas[0].AxisX.Maximum) {
+        var point = new DataPoint();
+        point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+        point.YValues[0] = 1;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+    }
+
+    protected IEnumerable<double> GetOriginalValues() {
+      IEnumerable<double> originalValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
+          break;
+        case TestSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+          break;
+        case AllSamples:
+          originalValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable);
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return originalValues;
+    }
+
+    protected IEnumerable<double> GetEstimatedValues(IRegressionSolution solution) {
+      IEnumerable<double> estimatedValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          estimatedValues = solution.EstimatedTrainingValues;
+          break;
+        case TestSamples:
+          estimatedValues = solution.EstimatedTestValues;
+          break;
+        case AllSamples:
+          estimatedValues = solution.EstimatedValues;
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return estimatedValues;
+    }
+
+    protected IEnumerable<double> GetMeanModelEstimatedValues(IEnumerable<double> originalValues) {
+      double averageTrainingTarget = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes).Average();
+      return Enumerable.Repeat(averageTrainingTarget, originalValues.Count());
+    }
+
+    protected virtual List<double> GetResiduals(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues) {
+      return originalValues.Zip(estimatedValues, (x, y) => Math.Abs(x - y)).ToList();
+    }
+
+    private double CalculateAreaOverCurve(Series series) {
+      if (series.Points.Count < 1) throw new ArgumentException("Could not calculate area under curve if less than 1 data points were given.");
+
+      double auc = 0.0;
+      for (int i = 1; i < series.Points.Count; i++) {
+        double width = series.Points[i].XValue - series.Points[i - 1].XValue;
+        double y1 = 1 - series.Points[i - 1].YValues[0];
+        double y2 = 1 - series.Points[i].YValues[0];
+
+        auc += (y1 + y2) * width / 2;
+      }
+
+      return auc;
+    }
+
+    protected void cmbSamples_SelectedIndexChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)cmbSamples_SelectedIndexChanged, sender, e);
+      else UpdateChart();
+    }
+  }
+}
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 6618)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 6647)
@@ -22,15 +22,13 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Core.Views;
 using HeuristicLab.Data;
 using HeuristicLab.Data.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
-using System.Globalization;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   [View("Estimated Values")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionEstimatedValuesView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionEstimatedValuesView : DataAnalysisSolutionEvaluationView {
     private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
     private const string ESTIMATEDVALUES_SERIES_NAME = "Estimated Values (all)";
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 6618)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 6647)
@@ -24,5 +24,4 @@
 using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -31,5 +30,5 @@
   [View("Line Chart")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionLineChartView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionLineChartView : DataAnalysisSolutionEvaluationView {
     private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
     private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 6618)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 6647)
@@ -25,5 +25,4 @@
 using System.Windows.Forms;
 using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
 using HeuristicLab.MainForm.WindowsForms;
@@ -32,5 +31,5 @@
   [View("Scatter Plot")]
   [Content(typeof(IRegressionSolution))]
-  public partial class RegressionSolutionScatterPlotView : ItemView, IRegressionSolutionEvaluationView {
+  public partial class RegressionSolutionScatterPlotView : DataAnalysisSolutionEvaluationView {
     private const string ALL_SERIES = "All samples";
     private const string TRAINING_SERIES = "Training samples";
