Index: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 5815)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 5816)
@@ -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="OnlineEvaluators\OnlineLinearScalingParameterCalculator.cs" />
-    <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationModel.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolution.cs" />
Index: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 5816)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 5816)
@@ -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: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 5815)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 5816)
@@ -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: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 5815)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 5816)
@@ -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: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 5816)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 5816)
@@ -0,0 +1,200 @@
+#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();
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionEnsembleSolution(this, cloner);
+    }
+
+    public override IEnumerable<double> EstimatedTrainingValues {
+      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.All(en => en.EstimatedValuesEnumerator.MoveNext())) {
+          int currentRow = rowsEnumerator.Current;
+
+          var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                    where trainingPartitions == null || !trainingPartitions.ContainsKey(pair.Model) ||
+                                         (trainingPartitions[pair.Model].Start >= currentRow && trainingPartitions[pair.Model].End < currentRow)
+                                    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.All(en => en.EstimatedValuesEnumerator.MoveNext())) {
+          int currentRow = rowsEnumerator.Current;
+
+          var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                    where testPartitions == null || !testPartitions.ContainsKey(pair.Model) ||
+                                      (testPartitions[pair.Model].Start >= currentRow && testPartitions[pair.Model].End < currentRow)
+                                    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: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 5815)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 5816)
@@ -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)";
@@ -99,4 +99,8 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionSolution(this, cloner);
+    }
+
     protected override void OnProblemDataChanged(EventArgs e) {
       base.OnProblemDataChanged(e);
Index: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 5816)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 5816)
@@ -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: branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs
===================================================================
--- branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 5816)
+++ branches/DataAnalysis SolutionEnsembles/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 5816)
@@ -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);
+  }
+}
