Index: /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 6183)
+++ /trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/CrossValidation.cs	(revision 6184)
@@ -373,7 +373,35 @@
       foreach (IResult result in ExtractAndAggregateResults<PercentValue>(resultCollections))
         results.Add(result.Name, result.Value);
-
+      foreach (IResult result in ExtractAndAggregateRegressionSolutions(resultCollections)) {
+        results.Add(result.Name, result.Value);
+      }
       results.Add("Execution Time", new TimeSpanValue(this.ExecutionTime));
       results.Add("CrossValidation Folds", new RunCollection(runs));
+    }
+
+    private IEnumerable<IResult> ExtractAndAggregateRegressionSolutions(IEnumerable<KeyValuePair<string, IItem>> resultCollections) {
+      Dictionary<string, List<IRegressionSolution>> resultSolutions = new Dictionary<string, List<IRegressionSolution>>();
+      foreach (var result in resultCollections) {
+        var regressionSolution = result.Value as IRegressionSolution;
+        if (regressionSolution != null) {
+          if (resultSolutions.ContainsKey(result.Key)) {
+            resultSolutions[result.Key].Add(regressionSolution);
+          } else {
+            resultSolutions.Add(result.Key, new List<IRegressionSolution>() { regressionSolution });
+          }
+        }
+      }
+      List<IResult> aggregatedResults = new List<IResult>();
+      foreach (KeyValuePair<string, List<IRegressionSolution>> solutions in resultSolutions) {
+        var problemDataClone = (IRegressionProblemData)Problem.ProblemData.Clone();
+        problemDataClone.TrainingPartition.Start = SamplesStart.Value; problemDataClone.TrainingPartition.End = SamplesEnd.Value;
+        problemDataClone.TestPartition.Start = SamplesStart.Value; problemDataClone.TestPartition.End = SamplesEnd.Value;
+        var ensembleSolution = new RegressionEnsembleSolution(solutions.Value.Select(x => x.Model), problemDataClone,
+          solutions.Value.Select(x => x.ProblemData.TrainingPartition),
+          solutions.Value.Select(x => x.ProblemData.TestPartition));
+
+        aggregatedResults.Add(new Result(solutions.Key, ensembleSolution));
+      }
+      return aggregatedResults;
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 6184)
@@ -158,4 +158,11 @@
       <DependentUpon>ClusteringSolutionView.cs</DependentUpon>
     </Compile>
+    <Compile Include="Interfaces\IRegressionEnsembleSolutionEvaluationView.cs" />
+    <Compile Include="RegressionEnsembleSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="RegressionEnsembleSolutionView.Designer.cs">
+      <DependentUpon>RegressionEnsembleSolutionView.cs</DependentUpon>
+    </Compile>
     <Compile Include="DiscriminantFunctionClassificationSolutionView.cs">
       <SubType>UserControl</SubType>
@@ -186,4 +193,16 @@
     <Compile Include="RegressionSolutionView.Designer.cs">
       <DependentUpon>RegressionSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionLineChartView.Designer.cs">
+      <DependentUpon>RegressionEnsembleSolutionLineChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionScatterPlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionScatterPlotView.Designer.cs">
+      <DependentUpon>RegressionEnsembleSolutionScatterPlotView.cs</DependentUpon>
     </Compile>
     <Compile Include="Regression\RegressionSolutionEstimatedValuesView.cs">
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs	(revision 6184)
@@ -0,0 +1,27 @@
+﻿#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
+
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public interface IRegressionEnsembleSolutionEvaluationView : IDataAnalysisSolutionEvaluationView {
+    new IRegressionEnsembleSolution Content { get; set; }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.Designer.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.Designer.cs	(revision 6184)
@@ -0,0 +1,84 @@
+﻿#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
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionEnsembleSolutionLineChartView {
+    /// <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.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
+      // 
+      // LineChartView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.chart);
+      this.Name = "LineChartView";
+      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: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionLineChartView.cs	(revision 6184)
@@ -0,0 +1,172 @@
+﻿#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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Line Chart")]
+  [Content(typeof(IRegressionEnsembleSolution))]
+  public partial class RegressionEnsembleSolutionLineChartView : ItemView, IRegressionEnsembleSolutionEvaluationView {
+    private const string TARGETVARIABLE_SERIES_NAME = "TargetVariable";
+    private const string ESTIMATEDTRAININGVALUES_SERIES_NAME = "EstimatedValues (training)";
+    private const string ESTIMATEDTESTVALUES_SERIES_NAME = "EstimatedValues (test)";
+
+    public new IRegressionEnsembleSolution Content {
+      get { return (IRegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionEnsembleSolutionLineChartView()
+      : 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].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.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.DataBindY(Content.ProblemData.Dataset.GetVariableValues(Content.ProblemData.TargetVariable));
+        this.UpdateStripLines();
+
+        var trainingIndizes = Enumerable.Range(Content.ProblemData.TrainingPartition.Start,
+          Content.ProblemData.TrainingPartition.End - Content.ProblemData.TrainingPartition.Start).ToArray();
+        var testIndizes = Enumerable.Range(Content.ProblemData.TestPartition.Start,
+          Content.ProblemData.TestPartition.End - Content.ProblemData.TestPartition.Start).ToArray();
+        this.chart.Series.Add(ESTIMATEDTRAININGVALUES_SERIES_NAME);
+        this.chart.Series[ESTIMATEDTRAININGVALUES_SERIES_NAME].LegendText = Content.ItemName;
+        this.chart.Series[ESTIMATEDTRAININGVALUES_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[ESTIMATEDTRAININGVALUES_SERIES_NAME].Points.DataBindXY(trainingIndizes, Content.EstimatedTrainingValues.ToArray());
+        this.chart.Series[ESTIMATEDTRAININGVALUES_SERIES_NAME].Tag = Content;
+
+        this.chart.Series.Add(ESTIMATEDTESTVALUES_SERIES_NAME);
+        this.chart.Series[ESTIMATEDTESTVALUES_SERIES_NAME].LegendText = Content.ItemName;
+        this.chart.Series[ESTIMATEDTESTVALUES_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[ESTIMATEDTESTVALUES_SERIES_NAME].Points.DataBindXY(testIndizes, Content.EstimatedTestValues.ToArray());
+        this.chart.Series[ESTIMATEDTESTVALUES_SERIES_NAME].Tag = Content;
+        UpdateCursorInterval();
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ESTIMATEDTRAININGVALUES_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);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      UpdateEstimatedValuesLineChart();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+
+    private void UpdateEstimatedValuesLineChart() {
+      if (InvokeRequired) Invoke((Action)UpdateEstimatedValuesLineChart);
+      else {
+        if (this.chart.Series.Count > 0) {
+          Series trainingSeries = this.chart.Series[ESTIMATEDTRAININGVALUES_SERIES_NAME];
+          if (trainingSeries != null) {
+            trainingSeries.Points.DataBindY(Content.EstimatedTrainingValues.ToArray());
+            trainingSeries.LegendText = Content.ItemName;
+          }
+          Series testSeries = this.chart.Series[ESTIMATEDTESTVALUES_SERIES_NAME];
+          if (testSeries != null) {
+            testSeries.Points.DataBindY(Content.EstimatedTestValues.ToArray());
+            testSeries.LegendText = Content.ItemName;
+          }
+          this.UpdateStripLines();
+          UpdateCursorInterval();
+        }
+      }
+    }
+
+    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();
+      //this.CreateAndAddStripLine("Training", Color.FromArgb(20, Color.Green),
+      //  Content.ProblemData.TrainingPartition.Start,
+      //  Content.ProblemData.TrainingPartition.End);
+      //this.CreateAndAddStripLine("Test", Color.FromArgb(20, Color.Red),
+      //  Content.ProblemData.TestPartition.Start,
+      //  Content.ProblemData.TestPartition.End);
+    }
+
+    private void CreateAndAddStripLine(string title, Color c, int start, int end) {
+      //StripLine stripLine = new StripLine();
+      //stripLine.BackColor = c;
+      //stripLine.Text = title;
+      //stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
+      //stripLine.StripWidth = end - start;
+      //stripLine.IntervalOffset = start;
+      //this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.Designer.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.Designer.cs	(revision 6184)
@@ -0,0 +1,86 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionEnsembleSolutionScatterPlotView {
+    /// <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(527, 392);
+      this.chart.TabIndex = 1;
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(chart_CustomizeLegend);
+      // 
+      // ScatterPlotView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Controls.Add(this.chart);
+      this.Name = "ScatterPlotView";
+      this.AllowDrop = true;
+      this.Size = new System.Drawing.Size(527, 392);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionScatterPlotView.cs	(revision 6184)
@@ -0,0 +1,228 @@
+﻿#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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Scatter Plot")]
+  [Content(typeof(IRegressionEnsembleSolution))]
+  public partial class RegressionEnsembleSolutionScatterPlotView : ItemView, IRegressionEnsembleSolutionEvaluationView {
+    private const string ALL_SERIES = "All samples";
+    private const string TRAINING_SERIES = "Training samples";
+    private const string TEST_SERIES = "Test samples";
+
+    public new IRegressionEnsembleSolution Content {
+      get { return (IRegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionEnsembleSolutionScatterPlotView()
+      : base() {
+      InitializeComponent();
+
+      this.chart.Series.Add(ALL_SERIES);
+      this.chart.Series[ALL_SERIES].LegendText = ALL_SERIES;
+      this.chart.Series[ALL_SERIES].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.Series.Add(TRAINING_SERIES);
+      this.chart.Series[TRAINING_SERIES].LegendText = TRAINING_SERIES;
+      this.chart.Series[TRAINING_SERIES].ChartType = SeriesChartType.FastPoint;
+      this.chart.Series[TRAINING_SERIES].Points.Add(1.0);
+
+      this.chart.Series.Add(TEST_SERIES);
+      this.chart.Series[TEST_SERIES].LegendText = TEST_SERIES;
+      this.chart.Series[TEST_SERIES].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
+      this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged);
+
+      //configure axis 
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].AxisX.Title = "Estimated 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;
+    }
+
+    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) {
+      UpdateChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      UpdateSeries();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    private void UpdateChart() {
+      if (InvokeRequired) Invoke((Action)UpdateChart);
+      else {
+        if (Content != null) {
+          this.UpdateSeries();
+          if (!this.chart.Series.Any(s => s.Points.Count > 0))
+            this.ClearChart();
+        }
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ALL_SERIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);
+      var targetValues = this.chart.Series[ALL_SERIES].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 zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
+      this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;
+      this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;
+    }
+
+
+    private void UpdateSeries() {
+      if (InvokeRequired) Invoke((Action)UpdateSeries);
+      else {
+        string targetVariableName = Content.ProblemData.TargetVariable;
+        Dataset dataset = Content.ProblemData.Dataset;
+        var trainingIndizes = Enumerable.Range(Content.ProblemData.TrainingPartition.Start, Content.ProblemData.TrainingPartition.End - Content.ProblemData.TrainingPartition.Start);
+        var testIndizes = Enumerable.Range(Content.ProblemData.TestPartition.Start, Content.ProblemData.TestPartition.End - Content.ProblemData.TestPartition.Start);
+        if (this.chart.Series[ALL_SERIES].Points.Count > 0)
+          this.chart.Series[ALL_SERIES].Points.DataBindXY(Content.EstimatedValues.ToArray(), "",
+            dataset.GetVariableValues(targetVariableName), "");
+        if (this.chart.Series[TRAINING_SERIES].Points.Count > 0)
+          this.chart.Series[TRAINING_SERIES].Points.DataBindXY(Content.EstimatedTrainingValues.ToArray(), "",
+            dataset.GetEnumeratedVariableValues(targetVariableName, trainingIndizes).ToArray(), "");
+        if (this.chart.Series[TEST_SERIES].Points.Count > 0)
+          this.chart.Series[TEST_SERIES].Points.DataBindXY(Content.EstimatedTestValues.ToArray(), "",
+           dataset.GetEnumeratedVariableValues(targetVariableName, testIndizes).ToArray(), "");
+
+        double max = Math.Max(Content.EstimatedValues.Max(), dataset.GetVariableValues(targetVariableName).Max());
+        double min = Math.Min(Content.EstimatedValues.Min(), dataset.GetVariableValues(targetVariableName).Min());
+
+        max = max + 0.2 * Math.Abs(max);
+        min = min - 0.2 * Math.Abs(min);
+
+        double interestingValuesRange = max - min;
+        int digits = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRange));
+
+        max = Math.Round(max, digits);
+        min = Math.Round(min, digits);
+
+        this.chart.ChartAreas[0].AxisX.Maximum = max;
+        this.chart.ChartAreas[0].AxisX.Minimum = min;
+        this.chart.ChartAreas[0].AxisY.Maximum = max;
+        this.chart.ChartAreas[0].AxisY.Minimum = min;
+        UpdateCursorInterval();
+      }
+    }
+
+    private void ClearChart() {
+      this.chart.Series[ALL_SERIES].Points.Clear();
+      this.chart.Series[TRAINING_SERIES].Points.Clear();
+      this.chart.Series[TEST_SERIES].Points.Clear();
+    }
+
+    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)) {
+          series.Points.Clear();
+        }
+      } else if (Content != null) {
+        string targetVariableName = Content.ProblemData.TargetVariable;
+
+        IEnumerable<double> predictedValues = null;
+        IEnumerable<double> targetValues = null; 
+        var trainingIndizes = Enumerable.Range(Content.ProblemData.TrainingPartition.Start, Content.ProblemData.TrainingPartition.End - Content.ProblemData.TrainingPartition.Start);
+        var testIndizes = Enumerable.Range(Content.ProblemData.TestPartition.Start, Content.ProblemData.TestPartition.End - Content.ProblemData.TestPartition.Start);
+
+        switch (series.Name) {
+          case ALL_SERIES:
+            predictedValues = Content.EstimatedValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetVariableValues(targetVariableName);
+            break;
+          case TRAINING_SERIES:
+            predictedValues = Content.EstimatedTrainingValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetEnumeratedVariableValues(targetVariableName, trainingIndizes).ToArray();
+            break;
+          case TEST_SERIES:
+            predictedValues = Content.EstimatedTestValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetEnumeratedVariableValues(targetVariableName, testIndizes).ToArray();
+            break;
+        }
+        series.Points.DataBindXY(predictedValues, "", targetValues, "");
+        this.chart.Legends[series.Legend].ForeColor = Color.Black;
+        UpdateCursorInterval();
+      }
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        this.ToggleSeriesData(result.Series);
+      }
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+
+    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
+      this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[ALL_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[TRAINING_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[TEST_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.Designer.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.Designer.cs	(revision 6184)
@@ -0,0 +1,87 @@
+﻿#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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionEnsembleSolutionView {
+    /// <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.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Regression Solution";
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // RegressionSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "RegressionSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.4/RegressionEnsembleSolutionView.cs	(revision 6184)
@@ -0,0 +1,44 @@
+﻿#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.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("RegressionEnsembleSolution View")]
+  [Content(typeof(RegressionEnsembleSolution), true)]
+  public partial class RegressionEnsembleSolutionView : DataAnalysisSolutionView {
+    public RegressionEnsembleSolutionView() {
+      InitializeComponent();
+
+      var regressionEnsembleSolutionEvaluationViewTypes = ApplicationManager.Manager.GetTypes(typeof(IRegressionEnsembleSolutionEvaluationView), true);
+      foreach (Type viewType in regressionEnsembleSolutionEvaluationViewTypes)
+        AddViewListViewItem(viewType);
+    }
+
+    public new RegressionSolution Content {
+      get { return (RegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 6184)
@@ -109,4 +109,7 @@
   <ItemGroup>
     <Compile Include="DoubleLimit.cs" />
+    <Compile Include="Implementation\Classification\ClassificationEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="Implementation\Classification\ClassificationProblemData.cs" />
     <Compile Include="Implementation\Classification\ClassificationProblem.cs" />
@@ -115,10 +118,18 @@
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
-    <Compile Include="Implementation\Classification\ClassificationEnsembleModel.cs" />
+    <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Interfaces\Classification\IClassificationEnsembleSolution.cs" />
     <Compile Include="Interfaces\Classification\IDiscriminantFunctionThresholdCalculator.cs" />
-    <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs" />
-    <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="OnlineCalculators\OnlineLinearScalingParameterCalculator.cs" />
-    <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationModel.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolution.cs" />
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 6184)
@@ -0,0 +1,90 @@
+#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents classification solutions that contain an ensemble of multiple classification models
+  /// </summary>
+  [StorableClass]
+  [Item("Classification Ensemble Solution", "A classification solution that contains an ensemble of multiple classification models")]
+  // [Creatable("Data Analysis")]
+  public class ClassificationEnsembleSolution : NamedItem, IClassificationEnsembleSolution {
+
+    [Storable]
+    private List<IClassificationModel> models;
+    public IEnumerable<IClassificationModel> Models {
+      get { return new List<IClassificationModel>(models); }
+    }
+    [StorableConstructor]
+    protected ClassificationEnsembleSolution(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleSolution(ClassificationEnsembleSolution original, Cloner cloner)
+      : base(original, cloner) {
+      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
+    }
+    public ClassificationEnsembleSolution(IEnumerable<IClassificationModel> models)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.models = new List<IClassificationModel>(models);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationEnsembleSolution(this, cloner);
+    }
+
+    #region IClassificationEnsembleModel Members
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    #endregion
+
+    #region IClassificationModel Members
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var estimatedValuesVector in GetEstimatedClassValueVectors(dataset, rows)) {
+        // return the class which is most often occuring
+        yield return
+          estimatedValuesVector
+          .GroupBy(x => x)
+          .OrderBy(g => -g.Count())
+          .Select(g => g.Key)
+          .First();
+      }
+    }
+
+    #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 6184)
@@ -30,8 +30,8 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   /// <summary>
-  /// Abstract base class for classification data analysis solutions
+  /// Represents a classification data analysis solution
   /// </summary>
   [StorableClass]
-  public abstract class ClassificationSolution : DataAnalysisSolution, IClassificationSolution {
+  public class ClassificationSolution : DataAnalysisSolution, IClassificationSolution {
     private const string TrainingAccuracyResultName = "Accuracy (training)";
     private const string TestAccuracyResultName = "Accuracy (test)";
@@ -67,4 +67,8 @@
       Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue()));
       RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationSolution(this, cloner);
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 6184)
@@ -27,8 +27,8 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   /// <summary>
-  /// Abstract base class for clustering data analysis solutions
+  /// Represents a clustering data analysis solution
   /// </summary>
   [StorableClass]
-  public abstract class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
+  public class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
 
     [StorableConstructor]
@@ -39,4 +39,8 @@
     public ClusteringSolution(IClusteringModel model, IClusteringProblemData problemData)
       : base(model, problemData) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClusteringSolution(this, cloner);
     }
 
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 6184)
@@ -0,0 +1,233 @@
+#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.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents regression solutions that contain an ensemble of multiple regression models
+  /// </summary>
+  [StorableClass]
+  [Item("Regression Ensemble Solution", "A regression solution that contains an ensemble of multiple regression models")]
+  // [Creatable("Data Analysis")]
+  public class RegressionEnsembleSolution : RegressionSolution, IRegressionEnsembleSolution {
+    public new IRegressionEnsembleModel Model {
+      get { return (IRegressionEnsembleModel)base.Model; }
+    }
+
+    [Storable]
+    private Dictionary<IRegressionModel, IntRange> trainingPartitions;
+    [Storable]
+    private Dictionary<IRegressionModel, IntRange> testPartitions;
+
+    [StorableConstructor]
+    protected RegressionEnsembleSolution(bool deserializing) : base(deserializing) { }
+    protected RegressionEnsembleSolution(RegressionEnsembleSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public RegressionEnsembleSolution(IEnumerable<IRegressionModel> models, IRegressionProblemData problemData)
+      : base(new RegressionEnsembleModel(models), problemData) {
+      trainingPartitions = new Dictionary<IRegressionModel, IntRange>();
+      testPartitions = new Dictionary<IRegressionModel, IntRange>();
+      foreach (var model in models) {
+        trainingPartitions[model] = (IntRange)problemData.TrainingPartition.Clone();
+        testPartitions[model] = (IntRange)problemData.TestPartition.Clone();
+      }
+      RecalculateResults();
+    }
+
+    public RegressionEnsembleSolution(IEnumerable<IRegressionModel> models, IRegressionProblemData problemData, IEnumerable<IntRange> trainingPartitions, IEnumerable<IntRange> testPartitions)
+      : base(new RegressionEnsembleModel(models), problemData) {
+      this.trainingPartitions = new Dictionary<IRegressionModel, IntRange>();
+      this.testPartitions = new Dictionary<IRegressionModel, IntRange>();
+      var modelEnumerator = models.GetEnumerator();
+      var trainingPartitionEnumerator = trainingPartitions.GetEnumerator();
+      var testPartitionEnumerator = testPartitions.GetEnumerator();
+      while (modelEnumerator.MoveNext() & trainingPartitionEnumerator.MoveNext() & testPartitionEnumerator.MoveNext()) {
+        this.trainingPartitions[modelEnumerator.Current] = (IntRange)trainingPartitionEnumerator.Current.Clone();
+        this.testPartitions[modelEnumerator.Current] = (IntRange)testPartitionEnumerator.Current.Clone();
+      }
+      if (modelEnumerator.MoveNext() | trainingPartitionEnumerator.MoveNext() | testPartitionEnumerator.MoveNext()) {
+        throw new ArgumentException();
+      }
+
+      RecalculateResults();
+    }
+
+    private void RecalculateResults() {
+      double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
+      var trainingIndizes = Enumerable.Range(ProblemData.TrainingPartition.Start,
+        ProblemData.TrainingPartition.End - ProblemData.TrainingPartition.Start);
+      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, trainingIndizes);
+      double[] estimatedTestValues = EstimatedTestValues.ToArray(); // cache values
+      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TestIndizes);
+
+      OnlineCalculatorError errorState;
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionEnsembleSolution(this, cloner);
+    }
+
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get {
+        var rows = Enumerable.Range(ProblemData.TrainingPartition.Start, ProblemData.TrainingPartition.End - ProblemData.TrainingPartition.Start);
+        var estimatedValuesEnumerators = (from model in Model.Models
+                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, rows).GetEnumerator() })
+                                         .ToList();
+        var rowsEnumerator = rows.GetEnumerator();
+        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
+          int currentRow = rowsEnumerator.Current;
+
+          var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                    where trainingPartitions == null || !trainingPartitions.ContainsKey(pair.Model) ||
+                                         (trainingPartitions[pair.Model].Start <= currentRow && currentRow < trainingPartitions[pair.Model].End)
+                                    select pair.EstimatedValuesEnumerator;
+          yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
+        }
+      }
+    }
+
+    public override IEnumerable<double> EstimatedTestValues {
+      get {
+        var estimatedValuesEnumerators = (from model in Model.Models
+                                          select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndizes).GetEnumerator() })
+                                         .ToList();
+        var rowsEnumerator = ProblemData.TestIndizes.GetEnumerator();
+        while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
+          int currentRow = rowsEnumerator.Current;
+
+          var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                    where testPartitions == null || !testPartitions.ContainsKey(pair.Model) ||
+                                      (testPartitions[pair.Model].Start <= currentRow && currentRow < testPartitions[pair.Model].End)
+                                    select pair.EstimatedValuesEnumerator;
+
+          yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
+        }
+      }
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      return from xs in GetEstimatedValueVectors(ProblemData.Dataset, rows)
+             select AggregateEstimatedValues(xs);
+    }
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in Model.Models
+                                        select model.GetEstimatedValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    private double AggregateEstimatedValues(IEnumerable<double> estimatedValues) {
+      return estimatedValues.Average();
+    }
+
+    //[Storable]
+    //private string name;
+    //public string Name {
+    //  get {
+    //    return name;
+    //  }
+    //  set {
+    //    if (value != null && value != name) {
+    //      var cancelEventArgs = new CancelEventArgs<string>(value);
+    //      OnNameChanging(cancelEventArgs);
+    //      if (cancelEventArgs.Cancel == false) {
+    //        name = value;
+    //        OnNamedChanged(EventArgs.Empty);
+    //      }
+    //    }
+    //  }
+    //}
+
+    //public bool CanChangeName {
+    //  get { return true; }
+    //}
+
+    //[Storable]
+    //private string description;
+    //public string Description {
+    //  get {
+    //    return description;
+    //  }
+    //  set {
+    //    if (value != null && value != description) {
+    //      description = value;
+    //      OnDescriptionChanged(EventArgs.Empty);
+    //    }
+    //  }
+    //}
+
+    //public bool CanChangeDescription {
+    //  get { return true; }
+    //}
+
+    //#region events
+    //public event EventHandler<CancelEventArgs<string>> NameChanging;
+    //private void OnNameChanging(CancelEventArgs<string> cancelEventArgs) {
+    //  var listener = NameChanging;
+    //  if (listener != null) listener(this, cancelEventArgs);
+    //}
+
+    //public event EventHandler NameChanged;
+    //private void OnNamedChanged(EventArgs e) {
+    //  var listener = NameChanged;
+    //  if (listener != null) listener(this, e);
+    //}
+
+    //public event EventHandler DescriptionChanged;
+    //private void OnDescriptionChanged(EventArgs e) {
+    //  var listener = DescriptionChanged;
+    //  if (listener != null) listener(this, e);
+    //}
+    // #endregion
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 6184)
@@ -30,8 +30,8 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   /// <summary>
-  /// Abstract base class for regression data analysis solutions
+  /// Represents a regression data analysis solution
   /// </summary>
   [StorableClass]
-  public abstract class RegressionSolution : DataAnalysisSolution, IRegressionSolution {
+  public class RegressionSolution : DataAnalysisSolution, IRegressionSolution {
     private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
     private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
@@ -55,40 +55,40 @@
     public double TrainingMeanSquaredError {
       get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
     }
 
     public double TestMeanSquaredError {
       get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
     }
 
     public double TrainingRSquared {
       get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
     }
 
     public double TestRSquared {
       get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
     }
 
     public double TrainingRelativeError {
       get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
     }
 
     public double TestRelativeError {
       get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
     }
 
     public double TrainingNormalizedMeanSquaredError {
       get { return ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
     }
 
     public double TestNormalizedMeanSquaredError {
       get { return ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value; }
-      private set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+      protected set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
     }
 
@@ -113,4 +113,8 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionSolution(this, cloner);
+    }
+
     protected override void OnProblemDataChanged(EventArgs e) {
       base.OnProblemDataChanged(e);
@@ -122,5 +126,5 @@
     }
 
-    protected void RecalculateResults() {
+    private void RecalculateResults() {
       double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
       IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 6184)
@@ -0,0 +1,28 @@
+﻿#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.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationEnsembleSolution : IClassificationSolution {
+    IEnumerable<IClassificationModel> Models { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 6184)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 6184)
@@ -0,0 +1,29 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Core;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionEnsembleSolution : IRegressionSolution {
+    IRegressionEnsembleModel Model { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Tests/StatisticCalculatorsTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Tests/StatisticCalculatorsTest.cs	(revision 6183)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis/3.4/Tests/StatisticCalculatorsTest.cs	(revision 6184)
@@ -78,6 +78,6 @@
           double variance = calculator.Variance;
 
-          Assert.AreEqual(mean_alglib, mean, 1E-6 * scale);
-          Assert.AreEqual(variance_alglib, variance, 1E-6 * scale);
+          Assert.AreEqual(mean_alglib.ToString(), mean.ToString());
+          Assert.AreEqual(variance_alglib.ToString(), variance.ToString());
         }
       }
@@ -109,9 +109,35 @@
             double r2 = r2Calculator.RSquared;
 
-            Assert.AreEqual(r2_alglib, r2, 1E-6 * Math.Max(c1Scale, c2Scale));
+            Assert.AreEqual(r2_alglib.ToString(), r2.ToString());
           }
         }
       }
     }
+    [TestMethod]
+    public void CalculatePearsonsRSquaredOfConstantTest() {
+      System.Random random = new System.Random(31415);
+      int n = 12;
+      int cols = testData.GetLength(1);
+      for (int c1 = 0; c1 < cols; c1++) {
+        double c1Scale = random.NextDouble() * 1E7;
+        double c2Scale = 1.0;
+        IEnumerable<double> x = from rows in Enumerable.Range(0, n)
+                                select testData[rows, c1] * c1Scale;
+        IEnumerable<double> y = (new List<double>() { 150494407424305.44 })
+          .Concat(Enumerable.Repeat(150494407424305.47, n - 1));
+        double[] xs = x.ToArray();
+        double[] ys = y.ToArray();
+        double r2_alglib = alglib.pearsoncorrelation(xs, ys, n);
+        r2_alglib *= r2_alglib;
+
+        var r2Calculator = new OnlinePearsonsRSquaredCalculator();
+        for (int i = 0; i < n; i++) {
+          r2Calculator.Add(xs[i], ys[i]);
+        }
+        double r2 = r2Calculator.RSquared;
+
+        Assert.AreEqual(r2_alglib.ToString(), r2.ToString());
+      }
+    }
   }
 }
