Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/HeuristicLab.Algorithms.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/HeuristicLab.Algorithms.DataAnalysis.Views-3.4.csproj	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis.Views/3.4/HeuristicLab.Algorithms.DataAnalysis.Views-3.4.csproj	(revision 13948)
@@ -175,9 +175,4 @@
       <Private>False</Private>
     </Reference>
-    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
-      <Private>False</Private>
-    </Reference>
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -285,4 +280,8 @@
       <Name>HeuristicLab.Problems.DataAnalysis.Views-3.4</Name>
       <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{df87c13e-a889-46ff-8153-66dcaa8c5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
     </ProjectReference>
   </ItemGroup>
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs	(revision 13948)
@@ -139,5 +139,5 @@
       }
 
-      var model = new OneRClassificationModel(bestVariable, bestSplits.Select(s => s.thresholdValue).ToArray(), bestSplits.Select(s => s.classValue).ToArray(), bestMissingValuesClass);
+      var model = new OneRClassificationModel(problemData.TargetVariable, bestVariable, bestSplits.Select(s => s.thresholdValue).ToArray(), bestSplits.Select(s => s.classValue).ToArray(), bestMissingValuesClass);
       var solution = new OneRClassificationSolution(model, (IClassificationProblemData)problemData.Clone());
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs	(revision 13948)
@@ -31,5 +31,9 @@
   [StorableClass]
   [Item("OneR Classification Model", "A model that uses intervals for one variable to determine the class.")]
-  public class OneRClassificationModel : NamedItem, IClassificationModel {
+  public class OneRClassificationModel : ClassificationModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return new[] { Variable }; }
+    }
+
     [Storable]
     protected string variable;
@@ -66,6 +70,6 @@
     public override IDeepCloneable Clone(Cloner cloner) { return new OneRClassificationModel(this, cloner); }
 
-    public OneRClassificationModel(string variable, double[] splits, double[] classes, double missingValuesClass = double.NaN)
-      : base() {
+    public OneRClassificationModel(string targetVariable, string variable, double[] splits, double[] classes, double missingValuesClass = double.NaN)
+      : base(targetVariable) {
       if (splits.Length != classes.Length) {
         throw new ArgumentException("Number of splits and classes has to be equal.");
@@ -84,5 +88,5 @@
     // uses sorting to return the values in the order of rows, instead of using nested for loops
     // to avoid O(n²) runtime
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       var values = dataset.GetDoubleValues(Variable, rows).ToArray();
       var rowsArray = rows.ToArray();
@@ -108,5 +112,5 @@
     }
 
-    public IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
       return new OneRClassificationSolution(this, new ClassificationProblemData(problemData));
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs	(revision 13948)
@@ -64,4 +64,5 @@
     private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
     private const string CreateSolutionParameterName = "CreateSolution";
+    private const string StoreRunsParameterName = "StoreRuns";
     private const string RegressionAlgorithmSolutionResultParameterName = "RegressionAlgorithmResult";
 
@@ -106,4 +107,7 @@
       get { return (IFixedValueParameter<BoolValue>)Parameters[CreateSolutionParameterName]; }
     }
+    public IFixedValueParameter<BoolValue> StoreRunsParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[StoreRunsParameterName]; }
+    }
 
     #endregion
@@ -144,4 +148,9 @@
       get { return CreateSolutionParameter.Value.Value; }
       set { CreateSolutionParameter.Value.Value = value; }
+    }
+
+    public bool StoreRuns {
+      get { return StoreRunsParameter.Value.Value; }
+      set { StoreRunsParameter.Value.Value = value; }
     }
 
@@ -178,5 +187,5 @@
       var regressionAlgs = new ItemSet<IAlgorithm>(new IAlgorithm[] {
         new RandomForestRegression(),
-        sgp, 
+        sgp,
         mctsSymbReg
       });
@@ -206,4 +215,7 @@
         "Flag that indicates if a solution should be produced at the end of the run", new BoolValue(true)));
       Parameters[CreateSolutionParameterName].Hidden = true;
+      Parameters.Add(new FixedValueParameter<BoolValue>(StoreRunsParameterName,
+        "Flag that indicates if the results of the individual runs should be stored for detailed analysis", new BoolValue(false)));
+      Parameters[StoreRunsParameterName].Hidden = true;
     }
 
@@ -218,17 +230,18 @@
 
       var table = new DataTable("Qualities");
-      table.Rows.Add(new DataRow("Loss (train)"));
-      table.Rows.Add(new DataRow("Loss (test)"));
+      table.Rows.Add(new DataRow("R² (train)"));
+      table.Rows.Add(new DataRow("R² (test)"));
       Results.Add(new Result("Qualities", table));
       var curLoss = new DoubleValue();
       var curTestLoss = new DoubleValue();
-      Results.Add(new Result("Loss (train)", curLoss));
-      Results.Add(new Result("Loss (test)", curTestLoss));
+      Results.Add(new Result("R² (train)", curLoss));
+      Results.Add(new Result("R² (test)", curTestLoss));
       var runCollection = new RunCollection();
-      Results.Add(new Result("Runs", runCollection));
+      if (StoreRuns)
+        Results.Add(new Result("Runs", runCollection));
 
       // init
       var problemData = Problem.ProblemData;
-      var targetVarName = Problem.ProblemData.TargetVariable;
+      var targetVarName = problemData.TargetVariable;
       var activeVariables = problemData.AllowedInputVariables.Concat(new string[] { problemData.TargetVariable });
       var modifiableDataset = new ModifiableDataset(
@@ -273,6 +286,7 @@
           IRegressionModel model;
           IRun run;
+
           // try to find a model. The algorithm might fail to produce a model. In this case we just retry until the iterations are exhausted
-          if (TryExecute(alg, RegressionAlgorithmResult, out model, out run)) {
+          if (TryExecute(alg, rand.Next(), RegressionAlgorithmResult, out model, out run)) {
             int row = 0;
             // update predictions for training and test
@@ -303,7 +317,8 @@
           }
 
-          runCollection.Add(run);
-          table.Rows["Loss (train)"].Values.Add(curLoss.Value);
-          table.Rows["Loss (test)"].Values.Add(curTestLoss.Value);
+          if (StoreRuns)
+            runCollection.Add(run);
+          table.Rows["R² (train)"].Values.Add(curLoss.Value);
+          table.Rows["R² (test)"].Values.Add(curTestLoss.Value);
           iterations.Value = i + 1;
         }
@@ -317,6 +332,5 @@
           // just produce an ensemble solution for now (TODO: correct scaling or linear regression for ensemble model weights)
 
-          var ensembleModel = new RegressionEnsembleModel(models) { AverageModelEstimates = false };
-          var ensembleSolution = ensembleModel.CreateRegressionSolution((IRegressionProblemData)problemData.Clone());
+          var ensembleSolution = CreateEnsembleSolution(models, (IRegressionProblemData)problemData.Clone());
           Results.Add(new Result("EnsembleSolution", ensembleSolution));
         }
@@ -326,4 +340,42 @@
         alg.Prepare(true);
       }
+    }
+
+    private static IRegressionEnsembleSolution CreateEnsembleSolution(List<IRegressionModel> models,
+      IRegressionProblemData problemData) {
+      var rows = problemData.TrainingPartition.Size;
+      var features = models.Count;
+      double[,] inputMatrix = new double[rows, features + 1];
+      //add model estimates
+      for (int m = 0; m < models.Count; m++) {
+        var model = models[m];
+        var estimates = model.GetEstimatedValues(problemData.Dataset, problemData.TrainingIndices);
+        int estimatesCounter = 0;
+        foreach (var estimate in estimates) {
+          inputMatrix[estimatesCounter, m] = estimate;
+          estimatesCounter++;
+        }
+      }
+
+      //add target
+      var targets = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices);
+      int targetCounter = 0;
+      foreach (var target in targets) {
+        inputMatrix[targetCounter, models.Count] = target;
+        targetCounter++;
+      }
+
+      alglib.linearmodel lm = new alglib.linearmodel();
+      alglib.lrreport ar = new alglib.lrreport();
+      double[] coefficients;
+      int retVal = 1;
+      alglib.lrbuildz(inputMatrix, rows, features, out retVal, out lm, out ar);
+      if (retVal != 1) throw new ArgumentException("Error in calculation of linear regression solution");
+
+      alglib.lrunpack(lm, out coefficients, out features);
+
+      var ensembleModel = new RegressionEnsembleModel(models, coefficients.Take(models.Count)) { AverageModelEstimates = false };
+      var ensembleSolution = (IRegressionEnsembleSolution)ensembleModel.CreateRegressionSolution(problemData);
+      return ensembleSolution;
     }
 
@@ -391,5 +443,5 @@
       progRootNode.AddSubtree(startNode);
       var t = new SymbolicExpressionTree(progRootNode);
-      var combinedModel = new SymbolicRegressionModel(t, interpreter, lowerLimit, upperLimit);
+      var combinedModel = new SymbolicRegressionModel(problemData.TargetVariable, t, interpreter, lowerLimit, upperLimit);
       var sol = new SymbolicRegressionSolution(combinedModel, problemData);
       return sol;
@@ -405,8 +457,13 @@
     }
 
-    private static bool TryExecute(IAlgorithm alg, string regressionAlgorithmResultName, out IRegressionModel model, out IRun run) {
+    private static bool TryExecute(IAlgorithm alg, int seed, string regressionAlgorithmResultName, out IRegressionModel model, out IRun run) {
       model = null;
+      SetSeed(alg, seed);
       using (var wh = new AutoResetEvent(false)) {
-        EventHandler<EventArgs<Exception>> handler = (sender, args) => wh.Set();
+        Exception ex = null;
+        EventHandler<EventArgs<Exception>> handler = (sender, args) => {
+          ex = args.Value;
+          wh.Set();
+        };
         EventHandler handler2 = (sender, args) => wh.Set();
         alg.ExceptionOccurred += handler;
@@ -417,5 +474,7 @@
           wh.WaitOne();
 
+          if (ex != null) throw new AggregateException(ex);
           run = alg.Runs.Last();
+          alg.Runs.Clear();
           var sols = alg.Results.Select(r => r.Value).OfType<IRegressionSolution>();
           if (!sols.Any()) return false;
@@ -444,4 +503,17 @@
       return model != null;
     }
+
+    private static void SetSeed(IAlgorithm alg, int seed) {
+      // no common interface for algs that use a PRNG -> use naming convention to set seed
+      var paramItem = alg as IParameterizedItem;
+
+      if (paramItem.Parameters.ContainsKey("SetSeedRandomly")) {
+        ((BoolValue)paramItem.Parameters["SetSeedRandomly"].ActualValue).Value = false;
+        ((IntValue)paramItem.Parameters["Seed"].ActualValue).Value = seed;
+      } else {
+        throw new ArgumentException("Base learner does not have a seed parameter (algorithm {0})", alg.Name);
+      }
+
+    }
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceProduct.cs	(revision 13948)
@@ -94,5 +94,5 @@
     public static IList<double> GetGradient(double[,] x, int i, int j, List<ParameterizedCovarianceFunction> factorFunctions) {
       var covariances = factorFunctions.Select(f => f.Covariance(x, i, j)).ToArray();
-      var gr = new List<double>(factorFunctions.Sum(f => f.CovarianceGradient(x, i, j).Count));
+      var gr = new List<double>();
       for (int ii = 0; ii < factorFunctions.Count; ii++) {
         foreach (var g in factorFunctions[ii].CovarianceGradient(x, i, j)) {
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/CovarianceFunctions/CovarianceSum.cs	(revision 13948)
@@ -88,5 +88,5 @@
       sum.CrossCovariance = (x, xt, i, j) => functions.Select(e => e.CrossCovariance(x, xt, i, j)).Sum();
       sum.CovarianceGradient = (x, i, j) => {
-        var g = new List<double>(functions.Sum(e => e.CovarianceGradient(x, i, j).Count));
+        var g = new List<double>();
         foreach (var e in functions)
           g.AddRange(e.CovarianceGradient(x, i, j));
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 13948)
@@ -34,5 +34,9 @@
   [StorableClass]
   [Item("GaussianProcessModel", "Represents a Gaussian process posterior.")]
-  public sealed class GaussianProcessModel : NamedItem, IGaussianProcessModel {
+  public sealed class GaussianProcessModel : RegressionModel, IGaussianProcessModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
     [Storable]
     private double negativeLogLikelihood;
@@ -61,9 +65,5 @@
       get { return meanFunction; }
     }
-    [Storable]
-    private string targetVariable;
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -128,5 +128,4 @@
       this.trainingDataset = cloner.Clone(original.trainingDataset);
       this.negativeLogLikelihood = original.negativeLogLikelihood;
-      this.targetVariable = original.targetVariable;
       this.sqrSigmaNoise = original.sqrSigmaNoise;
       if (original.meanParameter != null) {
@@ -147,10 +146,9 @@
       IEnumerable<double> hyp, IMeanFunction meanFunction, ICovarianceFunction covarianceFunction,
       bool scaleInputs = true)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.meanFunction = (IMeanFunction)meanFunction.Clone();
       this.covarianceFunction = (ICovarianceFunction)covarianceFunction.Clone();
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
 
@@ -182,5 +180,5 @@
 
       IEnumerable<double> y;
-      y = ds.GetDoubleValues(targetVariable, rows);
+      y = ds.GetDoubleValues(TargetVariable, rows);
 
       int n = x.GetLength(0);
@@ -301,12 +299,9 @@
 
     #region IRegressionModel Members
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return GetEstimatedValuesHelper(dataset, rows);
     }
-    public GaussianProcessRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new GaussianProcessRegressionSolution(this, new RegressionProblemData(problemData));
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
     }
     #endregion
@@ -392,4 +387,5 @@
       }
     }
+
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs	(revision 13948)
@@ -34,5 +34,9 @@
   [StorableClass]
   [Item("StudentTProcessModel", "Represents a Student-t process posterior.")]
-  public sealed class StudentTProcessModel : NamedItem, IGaussianProcessModel {
+  public sealed class StudentTProcessModel : RegressionModel, IGaussianProcessModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
     [Storable]
     private double negativeLogLikelihood;
@@ -61,9 +65,5 @@
       get { return meanFunction; }
     }
-    [Storable]
-    private string targetVariable;
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -131,5 +131,4 @@
       this.trainingDataset = cloner.Clone(original.trainingDataset);
       this.negativeLogLikelihood = original.negativeLogLikelihood;
-      this.targetVariable = original.targetVariable;
       if (original.meanParameter != null) {
         this.meanParameter = (double[])original.meanParameter.Clone();
@@ -151,10 +150,9 @@
       IEnumerable<double> hyp, IMeanFunction meanFunction, ICovarianceFunction covarianceFunction,
       bool scaleInputs = true)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.meanFunction = (IMeanFunction)meanFunction.Clone();
       this.covarianceFunction = (ICovarianceFunction)covarianceFunction.Clone();
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
 
@@ -186,5 +184,5 @@
 
       IEnumerable<double> y;
-      y = ds.GetDoubleValues(targetVariable, rows);
+      y = ds.GetDoubleValues(TargetVariable, rows);
 
       int n = x.GetLength(0);
@@ -318,12 +316,9 @@
 
     #region IRegressionModel Members
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return GetEstimatedValuesHelper(dataset, rows);
     }
-    public GaussianProcessRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new GaussianProcessRegressionSolution(this, new RegressionProblemData(problemData));
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
     }
     #endregion
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs	(revision 13948)
@@ -33,5 +33,5 @@
   [Item("Gradient boosted tree model", "")]
   // this is essentially a collection of weighted regression models
-  public sealed class GradientBoostedTreesModel : NamedItem, IGradientBoostedTreesModel {
+  public sealed class GradientBoostedTreesModel : RegressionModel, IGradientBoostedTreesModel {
     // BackwardsCompatibility3.4 for allowing deserialization & serialization of old models
     #region Backwards compatible code, remove with 3.5
@@ -58,4 +58,8 @@
     #endregion
 
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
+    }
+
     private readonly IList<IRegressionModel> models;
     public IEnumerable<IRegressionModel> Models { get { return models; } }
@@ -77,6 +81,6 @@
     }
     [Obsolete("The constructor of GBTModel should not be used directly anymore (use GBTModelSurrogate instead)")]
-    public GradientBoostedTreesModel(IEnumerable<IRegressionModel> models, IEnumerable<double> weights)
-      : base("Gradient boosted tree model", string.Empty) {
+    internal GradientBoostedTreesModel(IEnumerable<IRegressionModel> models, IEnumerable<double> weights)
+      : base(string.Empty, "Gradient boosted tree model", string.Empty) {
       this.models = new List<IRegressionModel>(models);
       this.weights = new List<double>(weights);
@@ -89,5 +93,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       // allocate target array go over all models and add up weighted estimation for each row
       if (!rows.Any()) return Enumerable.Empty<double>(); // return immediately if rows is empty. This prevents multiple iteration over lazy rows enumerable.
@@ -105,7 +109,8 @@
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionSolution(this, (IRegressionProblemData)problemData.Clone());
     }
+
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs	(revision 13948)
@@ -22,4 +22,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -33,5 +34,5 @@
   // recalculate the actual GBT model on demand
   [Item("Gradient boosted tree model", "")]
-  public sealed class GradientBoostedTreesModelSurrogate : NamedItem, IGradientBoostedTreesModel {
+  public sealed class GradientBoostedTreesModelSurrogate : RegressionModel, IGradientBoostedTreesModel {
     // don't store the actual model!
     private IGradientBoostedTreesModel actualModel; // the actual model is only recalculated when necessary
@@ -55,4 +56,8 @@
 
 
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return actualModel.Models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
+    }
+
     [StorableConstructor]
     private GradientBoostedTreesModelSurrogate(bool deserializing) : base(deserializing) { }
@@ -73,6 +78,7 @@
 
     // create only the surrogate model without an actual model
-    public GradientBoostedTreesModelSurrogate(IRegressionProblemData trainingProblemData, uint seed, ILossFunction lossFunction, int iterations, int maxSize, double r, double m, double nu)
-      : base("Gradient boosted tree model", string.Empty) {
+    public GradientBoostedTreesModelSurrogate(IRegressionProblemData trainingProblemData, uint seed,
+      ILossFunction lossFunction, int iterations, int maxSize, double r, double m, double nu)
+      : base(trainingProblemData.TargetVariable, "Gradient boosted tree model", string.Empty) {
       this.trainingProblemData = trainingProblemData;
       this.seed = seed;
@@ -86,5 +92,7 @@
 
     // wrap an actual model in a surrograte
-    public GradientBoostedTreesModelSurrogate(IRegressionProblemData trainingProblemData, uint seed, ILossFunction lossFunction, int iterations, int maxSize, double r, double m, double nu, IGradientBoostedTreesModel model)
+    public GradientBoostedTreesModelSurrogate(IRegressionProblemData trainingProblemData, uint seed,
+      ILossFunction lossFunction, int iterations, int maxSize, double r, double m, double nu,
+      IGradientBoostedTreesModel model)
       : this(trainingProblemData, seed, lossFunction, iterations, maxSize, r, m, nu) {
       this.actualModel = model;
@@ -96,13 +104,12 @@
 
     // forward message to actual model (recalculate model first if necessary)
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       if (actualModel == null) actualModel = RecalculateModel();
       return actualModel.GetEstimatedValues(dataset, rows);
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionSolution(this, (IRegressionProblemData)problemData.Clone());
     }
-
 
     private IGradientBoostedTreesModel RecalculateModel() {
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeBuilder.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeBuilder.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeBuilder.cs	(revision 13948)
@@ -180,5 +180,5 @@
 
 
-    // processes potential splits from the queue as long as splits are left and the maximum size of the tree is not reached
+    // processes potential splits from the queue as long as splits are remaining and the maximum size of the tree is not reached
     private void CreateRegressionTreeFromQueue(int maxNodes, ILossFunction lossFunction) {
       while (queue.Any() && curTreeNodeIdx + 1 < maxNodes) { // two nodes are created in each loop
@@ -204,5 +204,5 @@
 
         // overwrite existing leaf node with an internal node
-        tree[f.ParentNodeIdx] = new RegressionTreeModel.TreeNode(f.SplittingVariable, f.SplittingThreshold, leftTreeIdx, rightTreeIdx);
+        tree[f.ParentNodeIdx] = new RegressionTreeModel.TreeNode(f.SplittingVariable, f.SplittingThreshold, leftTreeIdx, rightTreeIdx, weightLeft: (splitIdx - startIdx + 1) / (double)(endIdx - startIdx + 1));
       }
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs	(revision 13948)
@@ -34,5 +34,8 @@
   [StorableClass]
   [Item("RegressionTreeModel", "Represents a decision tree for regression.")]
-  public sealed class RegressionTreeModel : NamedItem, IRegressionModel {
+  public sealed class RegressionTreeModel : RegressionModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return tree.Select(t => t.VarName).Where(v => v != TreeNode.NO_VARIABLE); }
+    }
 
     // trees are represented as a flat array    
@@ -40,5 +43,5 @@
       public readonly static string NO_VARIABLE = null;
 
-      public TreeNode(string varName, double val, int leftIdx = -1, int rightIdx = -1)
+      public TreeNode(string varName, double val, int leftIdx = -1, int rightIdx = -1, double weightLeft = -1.0)
         : this() {
         VarName = varName;
@@ -46,10 +49,13 @@
         LeftIdx = leftIdx;
         RightIdx = rightIdx;
-      }
-
-      public string VarName { get; private set; } // name of the variable for splitting or NO_VARIABLE if terminal node
-      public double Val { get; private set; } // threshold
-      public int LeftIdx { get; private set; }
-      public int RightIdx { get; private set; }
+        WeightLeft = weightLeft;
+      }
+
+      public string VarName { get; internal set; } // name of the variable for splitting or NO_VARIABLE if terminal node
+      public double Val { get; internal set; } // threshold
+      public int LeftIdx { get; internal set; }
+      public int RightIdx { get; internal set; }
+      public double WeightLeft { get; internal set; } // for partial dependence plots (value in range [0..1] describes the fraction of training samples for the left sub-tree
+
 
       // necessary because the default implementation of GetHashCode for structs in .NET would only return the hashcode of val here
@@ -64,4 +70,5 @@
             LeftIdx.Equals(other.LeftIdx) &&
             RightIdx.Equals(other.RightIdx) &&
+            WeightLeft.Equals(other.WeightLeft) &&
             EqualStrings(VarName, other.VarName);
         } else {
@@ -79,11 +86,69 @@
     private TreeNode[] tree;
 
-    [Storable]
+    #region old storable format
+    // remove with HL 3.4
+    [Storable(AllowOneWay = true)]
     // to prevent storing the references to data caches in nodes
-    // TODO seemingly it is bad (performance-wise) to persist tuples (tuples are used as keys in a dictionary)
+    // seemingly, it is bad (performance-wise) to persist tuples (tuples are used as keys in a dictionary)
     private Tuple<string, double, int, int>[] SerializedTree {
-      get { return tree.Select(t => Tuple.Create(t.VarName, t.Val, t.LeftIdx, t.RightIdx)).ToArray(); }
-      set { this.tree = value.Select(t => new TreeNode(t.Item1, t.Item2, t.Item3, t.Item4)).ToArray(); }
-    }
+      // get { return tree.Select(t => Tuple.Create(t.VarName, t.Val, t.LeftIdx, t.RightIdx)).ToArray(); }
+      set { this.tree = value.Select(t => new TreeNode(t.Item1, t.Item2, t.Item3, t.Item4, -1.0)).ToArray(); } // use a weight of -1.0 to indicate that partial dependence cannot be calculated for old models 
+    }
+    #endregion
+    #region new storable format
+    [Storable]
+    private string[] SerializedTreeVarNames {
+      get { return tree.Select(t => t.VarName).ToArray(); }
+      set {
+        if (tree == null) tree = new TreeNode[value.Length];
+        for (int i = 0; i < value.Length; i++) {
+          tree[i].VarName = value[i];
+        }
+      }
+    }
+    [Storable]
+    private double[] SerializedTreeValues {
+      get { return tree.Select(t => t.Val).ToArray(); }
+      set {
+        if (tree == null) tree = new TreeNode[value.Length];
+        for (int i = 0; i < value.Length; i++) {
+          tree[i].Val = value[i];
+        }
+      }
+    }
+    [Storable]
+    private int[] SerializedTreeLeftIdx {
+      get { return tree.Select(t => t.LeftIdx).ToArray(); }
+      set {
+        if (tree == null) tree = new TreeNode[value.Length];
+        for (int i = 0; i < value.Length; i++) {
+          tree[i].LeftIdx = value[i];
+        }
+      }
+    }
+    [Storable]
+    private int[] SerializedTreeRightIdx {
+      get { return tree.Select(t => t.RightIdx).ToArray(); }
+      set {
+        if (tree == null) tree = new TreeNode[value.Length];
+        for (int i = 0; i < value.Length; i++) {
+          tree[i].RightIdx = value[i];
+        }
+      }
+    }
+    [Storable]
+    private double[] SerializedTreeWeightLeft {
+      get { return tree.Select(t => t.WeightLeft).ToArray(); }
+      set {
+        if (tree == null) tree = new TreeNode[value.Length];
+        for (int i = 0; i < value.Length; i++) {
+          tree[i].WeightLeft = value[i];
+        }
+      }
+    }
+    #endregion
+
+
+
 
     [StorableConstructor]
@@ -98,6 +163,6 @@
     }
 
-    internal RegressionTreeModel(TreeNode[] tree)
-      : base("RegressionTreeModel", "Represents a decision tree for regression.") {
+    internal RegressionTreeModel(TreeNode[] tree, string target = "Target")
+      : base(target, "RegressionTreeModel", "Represents a decision tree for regression.") {
       this.tree = tree;
     }
@@ -108,6 +173,10 @@
         if (node.VarName == TreeNode.NO_VARIABLE)
           return node.Val;
-
-        if (columnCache[nodeIdx][row] <= node.Val)
+        if (columnCache[nodeIdx] == null) {
+          if (node.WeightLeft.IsAlmost(-1.0)) throw new InvalidOperationException("Cannot calculate partial dependence for trees loaded from older versions of HeuristicLab.");
+          // weighted average for partial dependence plot (recursive here because we need to calculate both sub-trees)
+          return node.WeightLeft * GetPredictionForRow(t, columnCache, node.LeftIdx, row) +
+                 (1.0 - node.WeightLeft) * GetPredictionForRow(t, columnCache, node.RightIdx, row);
+        } else if (columnCache[nodeIdx][row] <= node.Val)
           nodeIdx = node.LeftIdx;
         else
@@ -121,5 +190,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset ds, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset ds, IEnumerable<int> rows) {
       // lookup columns for variableNames in one pass over the tree to speed up evaluation later on
       ReadOnlyCollection<double>[] columnCache = new ReadOnlyCollection<double>[tree.Length];
@@ -127,5 +196,7 @@
       for (int i = 0; i < tree.Length; i++) {
         if (tree[i].VarName != TreeNode.NO_VARIABLE) {
-          columnCache[i] = ds.GetReadOnlyDoubleValues(tree[i].VarName);
+          // tree models also support calculating estimations if not all variables used for training are available in the dataset
+          if (ds.ColumnNames.Contains(tree[i].VarName))
+            columnCache[i] = ds.GetReadOnlyDoubleValues(tree[i].VarName);
         }
       }
@@ -133,5 +204,5 @@
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionSolution(this, new RegressionProblemData(problemData));
     }
@@ -148,8 +219,9 @@
       } else {
         return
-          TreeToString(n.LeftIdx, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2} <= {3:F}", part, string.IsNullOrEmpty(part) ? "" : " and ", n.VarName, n.Val))
-        + TreeToString(n.RightIdx, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2} >  {3:F}", part, string.IsNullOrEmpty(part) ? "" : " and ", n.VarName, n.Val));
-      }
-    }
+          TreeToString(n.LeftIdx, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2} <= {3:F} ({4:N3})", part, string.IsNullOrEmpty(part) ? "" : " and ", n.VarName, n.Val, n.WeightLeft))
+        + TreeToString(n.RightIdx, string.Format(CultureInfo.InvariantCulture, "{0}{1}{2}  >  {3:F} ({4:N3}))", part, string.IsNullOrEmpty(part) ? "" : " and ", n.VarName, n.Val, 1.0 - n.WeightLeft));
+      }
+    }
+
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 13948)
@@ -111,5 +111,5 @@
       IClassificationProblemData problemData,
       IEnumerable<int> rows) {
-      var model = new SymbolicDiscriminantFunctionClassificationModel(tree, interpreter, new AccuracyMaximizationThresholdCalculator());
+      var model = new SymbolicDiscriminantFunctionClassificationModel(problemData.TargetVariable, tree, interpreter, new AccuracyMaximizationThresholdCalculator());
       model.RecalculateModelParameters(problemData, rows);
       return model;
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 13948)
@@ -110,5 +110,5 @@
       addition.AddSubtree(cNode);
 
-      SymbolicRegressionSolution solution = new SymbolicRegressionSolution(new SymbolicRegressionModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter()), (IRegressionProblemData)problemData.Clone());
+      SymbolicRegressionSolution solution = new SymbolicRegressionSolution(new SymbolicRegressionModel(problemData.TargetVariable, tree, new SymbolicDataAnalysisExpressionTreeInterpreter()), (IRegressionProblemData)problemData.Clone());
       solution.Model.Name = "Linear Regression Model";
       solution.Name = "Linear Regression Solution";
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 13948)
@@ -95,5 +95,5 @@
       relClassError = alglib.mnlrelclserror(lm, inputMatrix, nRows);
 
-      MultinomialLogitClassificationSolution solution = new MultinomialLogitClassificationSolution((IClassificationProblemData)problemData.Clone(), new MultinomialLogitModel(lm, targetVariable, allowedInputVariables, classValues));
+      MultinomialLogitClassificationSolution solution = new MultinomialLogitClassificationSolution(new MultinomialLogitModel(lm, targetVariable, allowedInputVariables, classValues), (IClassificationProblemData)problemData.Clone());
       return solution;
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public MultinomialLogitClassificationSolution(IClassificationProblemData problemData, MultinomialLogitModel logitModel)
+    public MultinomialLogitClassificationSolution( MultinomialLogitModel logitModel,IClassificationProblemData problemData)
       : base(logitModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 13948)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("Multinomial Logit Model", "Represents a multinomial logit model for classification.")]
-  public sealed class MultinomialLogitModel : NamedItem, IClassificationModel {
+  public sealed class MultinomialLogitModel : ClassificationModel {
 
     private alglib.logitmodel logitModel;
@@ -48,6 +48,8 @@
     }
 
-    [Storable]
-    private string targetVariable;
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -64,14 +66,12 @@
       logitModel = new alglib.logitmodel();
       logitModel.innerobj.w = (double[])original.logitModel.innerobj.w.Clone();
-      targetVariable = original.targetVariable;
       allowedInputVariables = (string[])original.allowedInputVariables.Clone();
       classValues = (double[])original.classValues.Clone();
     }
     public MultinomialLogitModel(alglib.logitmodel logitModel, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.logitModel = logitModel;
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
       this.classValues = (double[])classValues.Clone();
@@ -82,5 +82,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
 
@@ -108,9 +108,6 @@
     }
 
-    public MultinomialLogitClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new MultinomialLogitClassificationSolution(new ClassificationProblemData(problemData), this);
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new MultinomialLogitClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
@@ -135,4 +132,5 @@
     }
     #endregion
+
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 13948)
@@ -25,5 +25,4 @@
 using System.Linq;
 using HeuristicLab.Algorithms.DataAnalysis.MctsSymbolicRegression.Policies;
-using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -177,5 +176,5 @@
 
           var t = new SymbolicExpressionTree(treeGen.Exec(bestCode, bestConsts, bestNParams, scalingFactor, scalingOffset));
-          var model = new SymbolicRegressionModel(t, interpreter, lowerEstimationLimit, upperEstimationLimit);
+          var model = new SymbolicRegressionModel(problemData.TargetVariable, t, interpreter, lowerEstimationLimit, upperEstimationLimit);
 
           // model has already been scaled linearly in Eval
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 13948)
@@ -40,5 +40,5 @@
       : base(original, cloner) {
     }
-    public NcaClassificationSolution(IClassificationProblemData problemData, INcaModel ncaModel)
+    public NcaClassificationSolution(INcaModel ncaModel, IClassificationProblemData problemData)
       : base(ncaModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 13948)
@@ -30,5 +30,8 @@
   [Item("NCA Model", "")]
   [StorableClass]
-  public class NcaModel : NamedItem, INcaModel {
+  public class NcaModel : ClassificationModel, INcaModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
 
     [Storable]
@@ -39,6 +42,4 @@
     [Storable]
     private string[] allowedInputVariables;
-    [Storable]
-    private string targetVariable;
     [Storable]
     private INearestNeighbourModel nnModel;
@@ -52,14 +53,13 @@
       this.transformationMatrix = (double[,])original.transformationMatrix.Clone();
       this.allowedInputVariables = (string[])original.allowedInputVariables.Clone();
-      this.targetVariable = original.targetVariable;
       this.nnModel = cloner.Clone(original.nnModel);
       this.classValues = (double[])original.classValues.Clone();
     }
-    public NcaModel(int k, double[,] transformationMatrix, IDataset dataset, IEnumerable<int> rows, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues) {
+    public NcaModel(int k, double[,] transformationMatrix, IDataset dataset, IEnumerable<int> rows, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues)
+      : base(targetVariable) {
       Name = ItemName;
       Description = ItemDescription;
       this.transformationMatrix = (double[,])transformationMatrix.Clone();
       this.allowedInputVariables = allowedInputVariables.ToArray();
-      this.targetVariable = targetVariable;
       this.classValues = (double[])classValues.Clone();
 
@@ -72,15 +72,15 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       var ds = ReduceDataset(dataset, rows);
       return nnModel.GetEstimatedClassValues(ds, Enumerable.Range(0, ds.Rows));
     }
 
-    public INcaClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NcaClassificationSolution(new ClassificationProblemData(problemData), this);
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NcaClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+    INcaClassificationSolution INcaModel.CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NcaClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
@@ -88,5 +88,5 @@
       var data = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
 
-      var targets = dataset.GetDoubleValues(targetVariable, rows).ToArray();
+      var targets = dataset.GetDoubleValues(TargetVariable, rows).ToArray();
       var result = new double[data.GetLength(0), transformationMatrix.GetLength(1) + 1];
       for (int i = 0; i < data.GetLength(0); i++)
@@ -104,5 +104,5 @@
           .Range(0, transformationMatrix.GetLength(1))
           .Select(x => "X" + x.ToString())
-          .Concat(targetVariable.ToEnumerable()),
+          .Concat(TargetVariable.ToEnumerable()),
         Reduce(dataset, rows));
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs	(revision 13948)
@@ -81,5 +81,5 @@
     public static IClassificationSolution CreateNearestNeighbourClassificationSolution(IClassificationProblemData problemData, int k) {
       var problemDataClone = (IClassificationProblemData)problemData.Clone();
-      return new NearestNeighbourClassificationSolution(problemDataClone, Train(problemDataClone, k));
+      return new NearestNeighbourClassificationSolution(Train(problemDataClone, k), problemDataClone);
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NearestNeighbourClassificationSolution(IClassificationProblemData problemData, INearestNeighbourModel nnModel)
+    public NearestNeighbourClassificationSolution(INearestNeighbourModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 13948)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("NearestNeighbourModel", "Represents a nearest neighbour model for regression and classification.")]
-  public sealed class NearestNeighbourModel : NamedItem, INearestNeighbourModel {
+  public sealed class NearestNeighbourModel : ClassificationModel, INearestNeighbourModel {
 
     private alglib.nearestneighbor.kdtree kdTree;
@@ -48,6 +48,8 @@
     }
 
-    [Storable]
-    private string targetVariable;
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -91,14 +93,13 @@
 
       k = original.k;
-      targetVariable = original.targetVariable;
       allowedInputVariables = (string[])original.allowedInputVariables.Clone();
       if (original.classValues != null)
         this.classValues = (double[])original.classValues.Clone();
     }
-    public NearestNeighbourModel(IDataset dataset, IEnumerable<int> rows, int k, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null) {
+    public NearestNeighbourModel(IDataset dataset, IEnumerable<int> rows, int k, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
+      : base(targetVariable) {
       Name = ItemName;
       Description = ItemDescription;
       this.k = k;
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
 
@@ -163,5 +164,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       if (classValues == null) throw new InvalidOperationException("No class values are defined.");
       double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
@@ -201,15 +202,10 @@
     }
 
-    public INearestNeighbourRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NearestNeighbourRegressionSolution(new RegressionProblemData(problemData), this);
-    }
+
     IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
-    }
-    public INearestNeighbourClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NearestNeighbourClassificationSolution(new ClassificationProblemData(problemData), this);
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+      return new NearestNeighbourRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NearestNeighbourClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 13948)
@@ -80,5 +80,5 @@
     public static IRegressionSolution CreateNearestNeighbourRegressionSolution(IRegressionProblemData problemData, int k) {
       var clonedProblemData = (IRegressionProblemData)problemData.Clone();
-      return new NearestNeighbourRegressionSolution(clonedProblemData, Train(problemData, k));
+      return new NearestNeighbourRegressionSolution(Train(problemData, k), clonedProblemData);
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NearestNeighbourRegressionSolution(IRegressionProblemData problemData, INearestNeighbourModel nnModel)
+    public NearestNeighbourRegressionSolution(INearestNeighbourModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 13948)
@@ -220,5 +220,5 @@
 
       var problemDataClone = (IClassificationProblemData)problemData.Clone();
-      return new NeuralNetworkClassificationSolution(problemDataClone, new NeuralNetworkModel(multiLayerPerceptron, targetVariable, allowedInputVariables, problemDataClone.ClassValues.ToArray()));
+      return new NeuralNetworkClassificationSolution(new NeuralNetworkModel(multiLayerPerceptron, targetVariable, allowedInputVariables, problemDataClone.ClassValues.ToArray()), problemDataClone);
     }
     #endregion
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkClassificationSolution(IClassificationProblemData problemData, INeuralNetworkModel nnModel)
+    public NeuralNetworkClassificationSolution(INeuralNetworkModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 13948)
@@ -204,5 +204,5 @@
       relClassError = alglib.mlperelclserror(mlpEnsemble, inputMatrix, nRows);
       var problemDataClone = (IClassificationProblemData)problemData.Clone();
-      return new NeuralNetworkEnsembleClassificationSolution(problemDataClone, new NeuralNetworkEnsembleModel(mlpEnsemble, targetVariable, allowedInputVariables, problemDataClone.ClassValues.ToArray()));
+      return new NeuralNetworkEnsembleClassificationSolution(new NeuralNetworkEnsembleModel(mlpEnsemble, targetVariable, allowedInputVariables, problemDataClone.ClassValues.ToArray()), problemDataClone);
     }
     #endregion
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkEnsembleClassificationSolution(IClassificationProblemData problemData, INeuralNetworkEnsembleModel nnModel)
+    public NeuralNetworkEnsembleClassificationSolution(INeuralNetworkEnsembleModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 13948)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("NeuralNetworkEnsembleModel", "Represents a neural network ensemble for regression and classification.")]
-  public sealed class NeuralNetworkEnsembleModel : NamedItem, INeuralNetworkEnsembleModel {
+  public sealed class NeuralNetworkEnsembleModel : ClassificationModel, INeuralNetworkEnsembleModel {
 
     private alglib.mlpensemble mlpEnsemble;
@@ -46,4 +46,8 @@
         }
       }
+    }
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
     }
 
@@ -72,5 +76,5 @@
     }
     public NeuralNetworkEnsembleModel(alglib.mlpensemble mlpEnsemble, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
@@ -103,5 +107,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
 
@@ -129,15 +133,9 @@
     }
 
-    public INeuralNetworkEnsembleRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NeuralNetworkEnsembleRegressionSolution(new RegressionEnsembleProblemData(problemData), this);
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
-    }
-    public INeuralNetworkEnsembleClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NeuralNetworkEnsembleClassificationSolution(new ClassificationEnsembleProblemData(problemData), this);
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new NeuralNetworkEnsembleRegressionSolution(this, new RegressionEnsembleProblemData(problemData));
+    }
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NeuralNetworkEnsembleClassificationSolution(this, new ClassificationEnsembleProblemData(problemData));
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 13948)
@@ -190,5 +190,5 @@
       avgRelError = alglib.mlpeavgrelerror(mlpEnsemble, inputMatrix, nRows);
 
-      return new NeuralNetworkEnsembleRegressionSolution((IRegressionProblemData)problemData.Clone(), new NeuralNetworkEnsembleModel(mlpEnsemble, targetVariable, allowedInputVariables));
+      return new NeuralNetworkEnsembleRegressionSolution(new NeuralNetworkEnsembleModel(mlpEnsemble, targetVariable, allowedInputVariables), (IRegressionProblemData)problemData.Clone());
     }
     #endregion
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkEnsembleRegressionSolution(IRegressionProblemData problemData, INeuralNetworkEnsembleModel nnModel)
+    public NeuralNetworkEnsembleRegressionSolution(INeuralNetworkEnsembleModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
       RecalculateResults();
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 13948)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("NeuralNetworkModel", "Represents a neural network for regression and classification.")]
-  public sealed class NeuralNetworkModel : NamedItem, INeuralNetworkModel {
+  public sealed class NeuralNetworkModel : ClassificationModel, INeuralNetworkModel {
 
     private alglib.multilayerperceptron multiLayerPerceptron;
@@ -48,6 +48,8 @@
     }
 
-    [Storable]
-    private string targetVariable;
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -74,5 +76,4 @@
       multiLayerPerceptron.innerobj.x = (double[])original.multiLayerPerceptron.innerobj.x.Clone();
       multiLayerPerceptron.innerobj.y = (double[])original.multiLayerPerceptron.innerobj.y.Clone();
-      targetVariable = original.targetVariable;
       allowedInputVariables = (string[])original.allowedInputVariables.Clone();
       if (original.classValues != null)
@@ -80,9 +81,8 @@
     }
     public NeuralNetworkModel(alglib.multilayerperceptron multiLayerPerceptron, string targetVariable, IEnumerable<string> allowedInputVariables, double[] classValues = null)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.multiLayerPerceptron = multiLayerPerceptron;
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
       if (classValues != null)
@@ -111,5 +111,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, allowedInputVariables, rows);
 
@@ -137,15 +137,9 @@
     }
 
-    public INeuralNetworkRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new NeuralNetworkRegressionSolution(new RegressionProblemData(problemData), this);
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
-    }
-    public INeuralNetworkClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new NeuralNetworkClassificationSolution(new ClassificationProblemData(problemData), this);
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new NeuralNetworkRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new NeuralNetworkClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 13948)
@@ -207,5 +207,5 @@
       avgRelError = alglib.mlpavgrelerror(multiLayerPerceptron, inputMatrix, nRows);
 
-      return new NeuralNetworkRegressionSolution((IRegressionProblemData)problemData.Clone(), new NeuralNetworkModel(multiLayerPerceptron, targetVariable, allowedInputVariables));
+      return new NeuralNetworkRegressionSolution(new NeuralNetworkModel(multiLayerPerceptron, targetVariable, allowedInputVariables), (IRegressionProblemData)problemData.Clone());
     }
     #endregion
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkRegressionSolution(IRegressionProblemData problemData, INeuralNetworkModel nnModel)
+    public NeuralNetworkRegressionSolution(INeuralNetworkModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs	(revision 13948)
@@ -143,14 +143,14 @@
 
       if (CreateSolution) {
-        var solution = new RandomForestClassificationSolution((IClassificationProblemData)Problem.ProblemData.Clone(), model);
+        var solution = new RandomForestClassificationSolution(model, (IClassificationProblemData)Problem.ProblemData.Clone());
         Results.Add(new Result(RandomForestClassificationModelResultName, "The random forest classification solution.", solution));
       }
     }
-    
+
     // keep for compatibility with old API
     public static RandomForestClassificationSolution CreateRandomForestClassificationSolution(IClassificationProblemData problemData, int nTrees, double r, double m, int seed,
       out double rmsError, out double relClassificationError, out double outOfBagRmsError, out double outOfBagRelClassificationError) {
       var model = CreateRandomForestClassificationModel(problemData, nTrees, r, m, seed, out rmsError, out relClassificationError, out outOfBagRmsError, out outOfBagRelClassificationError);
-      return new RandomForestClassificationSolution((IClassificationProblemData)problemData.Clone(), model);
+      return new RandomForestClassificationSolution(model, (IClassificationProblemData)problemData.Clone());
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public RandomForestClassificationSolution(IClassificationProblemData problemData, IRandomForestModel randomForestModel)
+    public RandomForestClassificationSolution(IRandomForestModel randomForestModel, IClassificationProblemData problemData)
       : base(randomForestModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 13948)
@@ -34,5 +34,5 @@
   [StorableClass]
   [Item("RandomForestModel", "Represents a random forest for regression and classification.")]
-  public sealed class RandomForestModel : NamedItem, IRandomForestModel {
+  public sealed class RandomForestModel : ClassificationModel, IRandomForestModel {
     // not persisted
     private alglib.decisionforest randomForest;
@@ -44,4 +44,9 @@
       }
     }
+
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return originalTrainingData.AllowedInputVariables; }
+    }
+
 
     // instead of storing the data of the model itself
@@ -91,8 +96,8 @@
 
     // random forest models can only be created through the static factory methods CreateRegressionModel and CreateClassificationModel
-    private RandomForestModel(alglib.decisionforest randomForest,
+    private RandomForestModel(string targetVariable, alglib.decisionforest randomForest,
       int seed, IDataAnalysisProblemData originalTrainingData,
       int nTrees, double r, double m, double[] classValues = null)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
@@ -147,5 +152,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       double[,] inputData = AlglibUtil.PrepareInputMatrix(dataset, AllowedInputVariables, rows);
       AssertInputMatrix(inputData);
@@ -174,15 +179,10 @@
     }
 
-    public IRandomForestRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
-      return new RandomForestRegressionSolution(new RegressionProblemData(problemData), this);
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
-    }
-    public IRandomForestClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return new RandomForestClassificationSolution(new ClassificationProblemData(problemData), this);
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
+
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RandomForestRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new RandomForestClassificationSolution(this, new ClassificationProblemData(problemData));
     }
 
@@ -205,5 +205,5 @@
       outOfBagRmsError = rep.oobrmserror;
 
-      return new RandomForestModel(dForest, seed, problemData, nTrees, r, m);
+      return new RandomForestModel(problemData.TargetVariable, dForest, seed, problemData, nTrees, r, m);
     }
 
@@ -242,5 +242,5 @@
       outOfBagRelClassificationError = rep.oobrelclserror;
 
-      return new RandomForestModel(dForest, seed, problemData, nTrees, r, m, classValues);
+      return new RandomForestModel(problemData.TargetVariable, dForest, seed, problemData, nTrees, r, m, classValues);
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs	(revision 13948)
@@ -143,5 +143,5 @@
 
       if (CreateSolution) {
-        var solution = new RandomForestRegressionSolution((IRegressionProblemData)Problem.ProblemData.Clone(), model);
+        var solution = new RandomForestRegressionSolution(model, (IRegressionProblemData)Problem.ProblemData.Clone());
         Results.Add(new Result(RandomForestRegressionModelResultName, "The random forest regression solution.", solution));
       }
@@ -153,5 +153,5 @@
       var model = CreateRandomForestRegressionModel(problemData, nTrees, r, m, seed,
         out rmsError, out avgRelError, out outOfBagRmsError, out outOfBagAvgRelError);
-      return new RandomForestRegressionSolution((IRegressionProblemData)problemData.Clone(), model);
+      return new RandomForestRegressionSolution(model, (IRegressionProblemData)problemData.Clone());
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 13948)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public RandomForestRegressionSolution(IRegressionProblemData problemData, IRandomForestModel randomForestModel)
+    public RandomForestRegressionSolution(IRandomForestModel randomForestModel, IRegressionProblemData problemData)
       : base(randomForestModel, problemData) {
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 13948)
@@ -37,5 +37,9 @@
   [StorableClass]
   [Item("SupportVectorMachineModel", "Represents a support vector machine model.")]
-  public sealed class SupportVectorMachineModel : NamedItem, ISupportVectorMachineModel {
+  public sealed class SupportVectorMachineModel : ClassificationModel, ISupportVectorMachineModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
+    }
+
 
     private svm_model model;
@@ -83,6 +87,4 @@
 
     [Storable]
-    private string targetVariable;
-    [Storable]
     private string[] allowedInputVariables;
     [Storable]
@@ -96,5 +98,4 @@
       this.model = original.model;
       this.rangeTransform = original.rangeTransform;
-      this.targetVariable = original.targetVariable;
       this.allowedInputVariables = (string[])original.allowedInputVariables.Clone();
       if (original.classValues != null)
@@ -106,10 +107,9 @@
     }
     public SupportVectorMachineModel(svm_model model, RangeTransform rangeTransform, string targetVariable, IEnumerable<string> allowedInputVariables)
-      : base() {
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.model = model;
       this.rangeTransform = rangeTransform;
-      this.targetVariable = targetVariable;
       this.allowedInputVariables = allowedInputVariables.ToArray();
     }
@@ -123,14 +123,11 @@
       return GetEstimatedValuesHelper(dataset, rows);
     }
-    public SupportVectorRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new SupportVectorRegressionSolution(this, new RegressionProblemData(problemData));
     }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
-    }
     #endregion
 
     #region IClassificationModel Members
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       if (classValues == null) throw new NotSupportedException();
       // return the original class value instead of the predicted value of the model
@@ -152,14 +149,11 @@
     }
 
-    public SupportVectorClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
       return new SupportVectorClassificationSolution(this, new ClassificationProblemData(problemData));
-    }
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateClassificationSolution(problemData);
     }
     #endregion
     private IEnumerable<double> GetEstimatedValuesHelper(IDataset dataset, IEnumerable<int> rows) {
       // calculate predictions for the currently requested rows
-      svm_problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, targetVariable, allowedInputVariables, rows);
+      svm_problem problem = SupportVectorMachineUtil.CreateSvmProblem(dataset, TargetVariable, allowedInputVariables, rows);
       svm_problem scaledProblem = rangeTransform.Scale(problem);
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 13948)
@@ -134,5 +134,5 @@
 
       var interpreter = new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(problemData.TargetVariable);
-      var model = new SymbolicTimeSeriesPrognosisModel(tree, interpreter);
+      var model = new SymbolicTimeSeriesPrognosisModel(problemData.TargetVariable, tree, interpreter);
       var solution = model.CreateTimeSeriesPrognosisSolution((ITimeSeriesPrognosisProblemData)problemData.Clone());
       return solution;
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Algorithms.DataAnalysis/3.4/kMeans/KMeansClusteringModel.cs	(revision 13948)
@@ -37,4 +37,8 @@
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
+    }
+
+    public IEnumerable<string> VariablesUsedForPrediction {
+      get { return allowedInputVariables; }
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationCalculator.cs	(revision 13948)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationCalculator.cs	(revision 13948)
@@ -0,0 +1,138 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  public abstract class AbstractFeatureCorrelationCalculator {
+    private readonly BackgroundWorker backgroundWorker;
+
+    public AbstractFeatureCorrelationCalculator() {
+      backgroundWorker = new BackgroundWorker { WorkerReportsProgress = true, WorkerSupportsCancellation = true };
+
+      backgroundWorker.DoWork += BackgroundWorker_DoWork;
+      backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
+      backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
+    }
+
+    private BackgroundWorkerInfo bwInfo;
+    public void TryCancelCalculation() {
+      if (!backgroundWorker.IsBusy) return;
+
+      bwInfo = null;
+      backgroundWorker.CancelAsync();
+    }
+
+    protected static IEnumerable<int> GetRelevantIndices(IDataAnalysisProblemData problemData, string partition) {
+      IEnumerable<int> var;
+      if (partition.Equals(AbstractFeatureCorrelationView.TRAININGSAMPLES))
+        var = problemData.TrainingIndices;
+      else if (partition.Equals(AbstractFeatureCorrelationView.TESTSAMPLES))
+        var = problemData.TestIndices;
+      else var = Enumerable.Range(0, problemData.Dataset.Rows);
+      return var;
+    }
+
+    #region backgroundworker
+
+    protected void StartCalculation(BackgroundWorkerInfo info) {
+      bwInfo = info;
+      if (backgroundWorker.IsBusy) {
+        backgroundWorker.CancelAsync();
+        return;
+      }
+
+      backgroundWorker.RunWorkerAsync(bwInfo);
+    }
+
+    protected abstract void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e);
+
+    private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
+      BackgroundWorker worker = (BackgroundWorker)sender;
+      if (!e.Cancelled && !worker.CancellationPending) {
+        if (e.Error != null) {
+          ErrorHandling.ShowErrorDialog(e.Error);
+        } else {
+          OnCorrelationCalculationFinished((double[,])e.Result, bwInfo.Calculator, bwInfo.Partition, bwInfo.IgnoreMissingValues, bwInfo.Variable);
+        }
+      } else if (bwInfo != null) {
+        backgroundWorker.RunWorkerAsync(bwInfo);
+      }
+    }
+
+    #endregion
+
+    #region events
+    public class CorrelationCalculationFinishedArgs : EventArgs {
+      public double[,] Correlation { get; private set; }
+      public IDependencyCalculator Calculcator { get; private set; }
+      public string Partition { get; private set; }
+      public bool IgnoreMissingValues { get; private set; }
+      public string Variable { get; private set; }
+
+
+      public CorrelationCalculationFinishedArgs(double[,] correlation, IDependencyCalculator calculator, string partition, bool ignoreMissingValues, string variable = null) {
+        this.Correlation = correlation;
+        this.Calculcator = calculator;
+        this.Partition = partition;
+        this.IgnoreMissingValues = ignoreMissingValues;
+        this.Variable = variable;
+      }
+    }
+
+    public delegate void CorrelationCalculationFinishedHandler(object sender, CorrelationCalculationFinishedArgs e);
+    public event CorrelationCalculationFinishedHandler CorrelationCalculationFinished;
+    protected virtual void OnCorrelationCalculationFinished(double[,] correlation, IDependencyCalculator calculator, string partition, bool ignoreMissingValues, string variable = null) {
+      var handler = CorrelationCalculationFinished;
+      if (handler != null)
+        handler(this, new CorrelationCalculationFinishedArgs(correlation, calculator, partition, ignoreMissingValues, variable));
+    }
+
+    public event ProgressChangedEventHandler ProgressChanged;
+    protected virtual void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
+      var handler = ProgressChanged;
+      if (handler != null) {
+        handler(sender, e);
+      }
+    }
+    #endregion
+
+    protected class BackgroundWorkerInfo {
+      public IDataset Dataset { get; set; }
+      public IDependencyCalculator Calculator { get; set; }
+      public string Partition { get; set; }
+      public IEnumerable<int> Indices { get; set; }
+
+      public bool IgnoreMissingValues { get; set; }
+
+      public string Variable { get; set; }
+      public int Frames { get; set; }
+      public double[,] AlreadyCalculated { get; set; }
+    }
+  }
+}
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 13948)
@@ -37,7 +37,7 @@
     public const string TESTSAMPLES = "Test Samples";
 
-    public static readonly IList<string> Partitions = new List<string>() { ALLSAMPLES, TRAININGSAMPLES, TESTSAMPLES };
+    public static readonly IList<string> Partitions = new List<string>() { ALLSAMPLES, TRAININGSAMPLES, TESTSAMPLES }.AsReadOnly();
 
-    protected FeatureCorrelationCalculator fcc;
+    protected AbstractFeatureCorrelationCalculator CorrelationCalculator { get; set; }
 
     public new DataAnalysisProblemData Content {
@@ -49,5 +49,4 @@
       InitializeComponent();
       dataView.FormatPattern = "0.000";
-      fcc = new FeatureCorrelationCalculator();
       var calculators = ApplicationManager.Manager.GetInstances<IDependencyCalculator>();
       var calcList = calculators.OrderBy(c => c.Name).Select(c => new { Name = c.Name, Calculator = c }).ToList();
@@ -55,5 +54,5 @@
       correlationCalcComboBox.DisplayMember = "Name";
       correlationCalcComboBox.DataSource = calcList;
-      correlationCalcComboBox.SelectedItem = calcList.First(c => c.Calculator.GetType().Equals(typeof(PearsonsRDependenceCalculator)));
+      correlationCalcComboBox.SelectedItem = calcList.First(c => c.Calculator.GetType() == typeof(PearsonsRDependenceCalculator));
       partitionComboBox.DataSource = Partitions;
       partitionComboBox.SelectedItem = TRAININGSAMPLES;
@@ -61,13 +60,18 @@
     }
 
+    protected override void OnClosing(FormClosingEventArgs e) {
+      base.OnClosing(e);
+      CorrelationCalculator.TryCancelCalculation();
+    }
+
     protected override void RegisterContentEvents() {
       base.RegisterContentEvents();
-      fcc.ProgressCalculation += new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
-      fcc.CorrelationCalculationFinished += new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
+      CorrelationCalculator.ProgressChanged += FeatureCorrelation_ProgressChanged;
+      CorrelationCalculator.CorrelationCalculationFinished += FeatureCorrelation_CalculationFinished;
     }
 
     protected override void DeregisterContentEvents() {
-      fcc.CorrelationCalculationFinished -= new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
-      fcc.ProgressCalculation -= new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
+      CorrelationCalculator.ProgressChanged -= FeatureCorrelation_ProgressChanged;
+      CorrelationCalculator.CorrelationCalculationFinished -= FeatureCorrelation_CalculationFinished;
       base.DeregisterContentEvents();
     }
@@ -75,7 +79,6 @@
     protected override void OnContentChanged() {
       base.OnContentChanged();
-      fcc.TryCancelCalculation();
+      CorrelationCalculator.TryCancelCalculation();
       if (Content != null) {
-        fcc.ProblemData = Content;
         CalculateCorrelation();
       } else {
@@ -106,5 +109,7 @@
 
     protected abstract void CalculateCorrelation();
-    protected abstract void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e);
+
+    protected abstract void FeatureCorrelation_CalculationFinished(object sender,
+      AbstractFeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e);
 
     protected void UpdateDataView(DoubleMatrix correlation) {
@@ -121,5 +126,5 @@
     }
 
-    protected void Content_ProgressCalculation(object sender, ProgressChangedEventArgs e) {
+    protected void FeatureCorrelation_ProgressChanged(object sender, ProgressChangedEventArgs e) {
       if (!progressPanel.Visible && e.ProgressPercentage != progressBar.Maximum) {
         progressPanel.Show();
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs	(revision 13948)
@@ -24,99 +24,27 @@
 using System.ComponentModel;
 using System.Linq;
+using System.Threading.Tasks;
 using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   [NonDiscoverableType]
-  public class FeatureCorrelationCalculator : Object {
+  public sealed class FeatureCorrelationCalculator : AbstractFeatureCorrelationCalculator {
+    public FeatureCorrelationCalculator() : base() { }
 
-    private BackgroundWorker bw;
-    private BackgroundWorkerInfo bwInfo;
+    public void CalculateElements(IDataAnalysisProblemData problemData, IDependencyCalculator calc, string partition, bool ignoreMissingValues) {
+      var indices = GetRelevantIndices(problemData, partition);
+      var info = new BackgroundWorkerInfo {
+        Dataset = problemData.Dataset, Calculator = calc, Partition = partition, Indices = indices, IgnoreMissingValues = ignoreMissingValues
+      };
 
-    private IDataAnalysisProblemData problemData;
-    public IDataAnalysisProblemData ProblemData {
-      set {
-        if (bw != null) {
-          bw.CancelAsync();
-        }
-        problemData = value;
-      }
+      StartCalculation(info);
     }
 
-    public FeatureCorrelationCalculator()
-      : base() { }
+    protected override void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
+      BackgroundWorker worker = (BackgroundWorker)sender;
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
 
-    public FeatureCorrelationCalculator(IDataAnalysisProblemData problemData)
-      : base() {
-      this.problemData = problemData;
-    }
-
-    public void CalculateElements(IDependencyCalculator calc, string partition) {
-      CalculateElements(problemData.Dataset, calc, partition);
-    }
-
-    // returns true if any calculation takes place
-    public bool CalculateTimeframeElements(IDependencyCalculator calc, string partition, string variable, int frames, double[,] correlation = null) {
-      if (correlation == null || correlation.GetLength(1) <= frames) {
-        CalculateElements(problemData.Dataset, calc, partition, variable, frames, correlation);
-        return true;
-      } else {
-        return false;
-      }
-    }
-
-    public void TryCancelCalculation() {
-      if (bw != null && bw.IsBusy) {
-        bwInfo = null;
-        bw.CancelAsync();
-      }
-    }
-
-    private void CalculateElements(IDataset dataset, IDependencyCalculator calc, string partition, string variable = null, int frames = 0, double[,] alreadyCalculated = null) {
-      var indices = GetRelevantIndices(problemData, partition);
-      bwInfo = new BackgroundWorkerInfo {
-        Dataset = dataset, Calculator = calc, Partition = partition, Indices = indices,
-        Variable = variable, Frames = frames, AlreadyCalculated = alreadyCalculated
-      };
-      if (bw == null) {
-        bw = new BackgroundWorker();
-        bw.WorkerReportsProgress = true;
-        bw.WorkerSupportsCancellation = true;
-        bw.DoWork += new DoWorkEventHandler(BwDoWork);
-        bw.ProgressChanged += new ProgressChangedEventHandler(BwProgressChanged);
-        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BwRunWorkerCompleted);
-      }
-      if (bw.IsBusy) {
-        bw.CancelAsync();
-      } else {
-        bw.RunWorkerAsync(bwInfo);
-      }
-    }
-
-    private IEnumerable<int> GetRelevantIndices(IDataAnalysisProblemData problemData, string partition) {
-      IEnumerable<int> var;
-      if (partition.Equals(AbstractFeatureCorrelationView.TRAININGSAMPLES))
-        var = problemData.TrainingIndices;
-      else if (partition.Equals(AbstractFeatureCorrelationView.TESTSAMPLES))
-        var = problemData.TestIndices;
-      else var = Enumerable.Range(0, problemData.Dataset.Rows);
-      return var;
-    }
-
-    #region backgroundworker
-    private void BwDoWork(object sender, DoWorkEventArgs e) {
-      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
-      if (bwInfo.Variable == null) {
-        BwCalculateCorrelation(sender, e);
-      } else {
-        BwCalculateTimeframeCorrelation(sender, e);
-      }
-    }
-
-    private void BwCalculateCorrelation(object sender, DoWorkEventArgs e) {
-      BackgroundWorker worker = sender as BackgroundWorker;
-
-      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
       var dataset = bwInfo.Dataset;
-      IEnumerable<int> indices = bwInfo.Indices;
+      var indices = bwInfo.Indices.ToArray();
       IDependencyCalculator calc = bwInfo.Calculator;
 
@@ -125,19 +53,24 @@
       int length = doubleVariableNames.Count;
       double[,] elements = new double[length, length];
-      double calculations = (Math.Pow(length, 2) + length) / 2;
 
       worker.ReportProgress(0);
 
-      for (int i = 0; i < length; i++) {
-        for (int j = 0; j < i + 1; j++) {
-          if (worker.CancellationPending) {
-            worker.ReportProgress(100);
-            e.Cancel = true;
-            return;
-          }
-          IEnumerable<double> var1 = problemData.Dataset.GetDoubleValues(doubleVariableNames[i], indices);
-          IEnumerable<double> var2 = problemData.Dataset.GetDoubleValues(doubleVariableNames[j], indices);
+      for (int counter = 0; counter < length; counter++) {
+        if (worker.CancellationPending) {
+          worker.ReportProgress(100);
+          e.Cancel = true;
+          return;
+        }
 
-          elements[i, j] = calc.Calculate(var1, var2, out error);
+        var i = counter;
+        Parallel.ForEach(Enumerable.Range(i, length - i), j => {
+          var var1 = dataset.GetDoubleValues(doubleVariableNames[i], indices);
+          var var2 = dataset.GetDoubleValues(doubleVariableNames[j], indices);
+
+          if (bwInfo.IgnoreMissingValues) {
+            var filtered = FilterNaNValues(var1, var2);
+            elements[i, j] = calc.Calculate(filtered, out error);
+          } else
+            elements[i, j] = calc.Calculate(var1, var2, out error);
 
           if (!error.Equals(OnlineCalculatorError.None)) {
@@ -145,6 +78,7 @@
           }
           elements[j, i] = elements[i, j];
-          worker.ReportProgress((int)Math.Round((((Math.Pow(i, 2) + i) / 2 + j + 1.0) / calculations) * 100));
-        }
+
+        });
+        worker.ReportProgress((int)(((double)counter) / length * 100));
       }
       e.Result = elements;
@@ -152,114 +86,22 @@
     }
 
-    private void BwCalculateTimeframeCorrelation(object sender, DoWorkEventArgs e) {
-      BackgroundWorker worker = sender as BackgroundWorker;
 
-      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
-      var dataset = bwInfo.Dataset;
-      IEnumerable<int> indices = bwInfo.Indices;
-      IDependencyCalculator calc = bwInfo.Calculator;
-      string variable = bwInfo.Variable;
-      int frames = bwInfo.Frames;
-      double[,] alreadyCalculated = bwInfo.AlreadyCalculated;
+    private static IEnumerable<Tuple<double, double>> FilterNaNValues(IEnumerable<double> first, IEnumerable<double> second) {
+      var firstEnumerator = first.GetEnumerator();
+      var secondEnumerator = second.GetEnumerator();
 
-      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
-      OnlineCalculatorError error = OnlineCalculatorError.None;
-      int length = doubleVariableNames.Count;
-      double[,] elements = new double[length, frames + 1];
-      double calculations = (frames + 1) * length;
+      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
+        var firstValue = firstEnumerator.Current;
+        var secondValue = secondEnumerator.Current;
 
-      worker.ReportProgress(0);
+        if (double.IsNaN(firstValue)) continue;
+        if (double.IsNaN(secondValue)) continue;
 
-      int start = 0;
-      if (alreadyCalculated != null) {
-        for (int i = 0; i < alreadyCalculated.GetLength(0); i++) {
-          Array.Copy(alreadyCalculated, i * alreadyCalculated.GetLength(1), elements, i * elements.GetLength(1), alreadyCalculated.GetLength(1));
-        }
-        start = alreadyCalculated.GetLength(1);
+        yield return Tuple.Create(firstValue, secondValue);
       }
 
-      for (int i = 0; i < length; i++) {
-        for (int j = start; j <= frames; j++) {
-          if (worker.CancellationPending) {
-            worker.ReportProgress(100);
-            e.Cancel = true;
-            return;
-          }
-
-          IEnumerable<double> var1 = problemData.Dataset.GetDoubleValues(variable, indices);
-          IEnumerable<double> var2 = problemData.Dataset.GetDoubleValues(doubleVariableNames[i], indices);
-
-          var valuesInFrame = var1.Take(j);
-          var help = var1.Skip(j).ToList();
-          help.AddRange(valuesInFrame);
-          var1 = help;
-
-          elements[i, j] = calc.Calculate(var1, var2, out error);
-
-          if (!error.Equals(OnlineCalculatorError.None)) {
-            elements[i, j] = double.NaN;
-          }
-          worker.ReportProgress((int)((100.0 / calculations) * (i * (frames + 1) + j + 1)));
-        }
+      if (firstEnumerator.MoveNext() || secondEnumerator.MoveNext()) {
+        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
       }
-      e.Result = elements;
-      worker.ReportProgress(100);
-    }
-
-    private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
-      BackgroundWorker worker = sender as BackgroundWorker;
-      if (!e.Cancelled && !worker.CancellationPending) {
-        if (e.Error != null) {
-          ErrorHandling.ShowErrorDialog(e.Error);
-        } else {
-          OnCorrelationCalculationFinished((double[,])e.Result, bwInfo.Calculator, bwInfo.Partition, bwInfo.Variable);
-        }
-      } else if (bwInfo != null) {
-        bw.RunWorkerAsync(bwInfo);
-      }
-    }
-    #endregion
-
-    #region events
-    public class CorrelationCalculationFinishedArgs : EventArgs {
-      public double[,] Correlation { get; private set; }
-      public IDependencyCalculator Calculcator { get; private set; }
-      public string Partition { get; private set; }
-      public string Variable { get; private set; }
-
-      public CorrelationCalculationFinishedArgs(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
-        this.Correlation = correlation;
-        this.Calculcator = calculator;
-        this.Partition = partition;
-        this.Variable = variable;
-      }
-    }
-
-    public delegate void CorrelationCalculationFinishedHandler(object sender, CorrelationCalculationFinishedArgs e);
-    public event CorrelationCalculationFinishedHandler CorrelationCalculationFinished;
-    protected virtual void OnCorrelationCalculationFinished(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
-      var handler = CorrelationCalculationFinished;
-      if (handler != null)
-        handler(this, new CorrelationCalculationFinishedArgs(correlation, calculator, partition, variable));
-    }
-
-    public delegate void ProgressCalculationHandler(object sender, ProgressChangedEventArgs e);
-    public event ProgressCalculationHandler ProgressCalculation;
-    protected void BwProgressChanged(object sender, ProgressChangedEventArgs e) {
-      BackgroundWorker worker = sender as BackgroundWorker;
-      if (ProgressCalculation != null) {
-        ProgressCalculation(sender, e);
-      }
-    }
-    #endregion
-
-    private class BackgroundWorkerInfo {
-      public IDataset Dataset { get; set; }
-      public IDependencyCalculator Calculator { get; set; }
-      public string Partition { get; set; }
-      public IEnumerable<int> Indices { get; set; }
-      public string Variable { get; set; }
-      public int Frames { get; set; }
-      public double[,] AlreadyCalculated { get; set; }
     }
   }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 13948)
@@ -47,5 +47,49 @@
     /// </summary>
     private void InitializeComponent() {
+      this.ignoreMissingValuesCheckbox = new System.Windows.Forms.CheckBox();
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.progressPanel.SuspendLayout();
       this.SuspendLayout();
+      // 
+      // minimumLabel
+      // 
+      this.minimumLabel.Location = new System.Drawing.Point(707, 434);
+      // 
+      // maximumLabel
+      // 
+      this.maximumLabel.Location = new System.Drawing.Point(707, 2);
+      // 
+      // pictureBox
+      // 
+      this.pictureBox.Location = new System.Drawing.Point(727, 30);
+      this.pictureBox.Size = new System.Drawing.Size(35, 401);
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.ignoreMissingValuesCheckbox);
+      this.splitContainer.Size = new System.Drawing.Size(695, 450);
+      // 
+      // dataView
+      // 
+      this.dataView.Size = new System.Drawing.Size(695, 421);
+      // 
+      // ignoreMissingValuesCheckbox
+      // 
+      this.ignoreMissingValuesCheckbox.AutoSize = true;
+      this.ignoreMissingValuesCheckbox.CheckAlign = System.Drawing.ContentAlignment.MiddleRight;
+      this.ignoreMissingValuesCheckbox.Location = new System.Drawing.Point(481, 6);
+      this.ignoreMissingValuesCheckbox.Name = "ignoreMissingValuesCheckbox";
+      this.ignoreMissingValuesCheckbox.Size = new System.Drawing.Size(122, 17);
+      this.ignoreMissingValuesCheckbox.TabIndex = 11;
+      this.ignoreMissingValuesCheckbox.Text = "ignoreMissingValues";
+      this.ignoreMissingValuesCheckbox.UseVisualStyleBackColor = true;
+      this.ignoreMissingValuesCheckbox.CheckedChanged += new System.EventHandler(this.ignoreMissingValuesCheckbox_CheckedChanged);
       // 
       // FeatureCorrelationView
@@ -54,8 +98,19 @@
       this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
       this.Name = "FeatureCorrelationView";
-      this.Size = new System.Drawing.Size(569, 336);
+      this.Size = new System.Drawing.Size(789, 456);
+      ((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.progressPanel.ResumeLayout(false);
+      this.progressPanel.PerformLayout();
       this.ResumeLayout(false);
+
     }
     #endregion
+
+    private System.Windows.Forms.CheckBox ignoreMissingValuesCheckbox;
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs	(revision 13948)
@@ -34,8 +34,13 @@
 
     private FeatureCorrelationCache correlationCache;
+    private new FeatureCorrelationCalculator CorrelationCalculator {
+      get { return (FeatureCorrelationCalculator)base.CorrelationCalculator; }
+      set { base.CorrelationCalculator = value; }
+    }
 
     public FeatureCorrelationView()
       : base() {
       InitializeComponent();
+      CorrelationCalculator = new FeatureCorrelationCalculator();
       correlationCache = new FeatureCorrelationCache();
     }
@@ -49,4 +54,8 @@
     }
 
+    private void ignoreMissingValuesCheckbox_CheckedChanged(object sender, EventArgs e) {
+      CalculateCorrelation();
+    }
+
     protected override void CalculateCorrelation() {
       if (correlationCalcComboBox.SelectedItem == null) return;
@@ -56,9 +65,9 @@
       string partition = (string)partitionComboBox.SelectedValue;
       dataView.Enabled = false;
-      double[,] corr = correlationCache.GetCorrelation(calc, partition);
+      double[,] corr = correlationCache.GetCorrelation(calc, partition, ignoreMissingValuesCheckbox.Checked);
       if (corr == null) {
-        fcc.CalculateElements(calc, partition);
+        CorrelationCalculator.CalculateElements(Content, calc, partition, ignoreMissingValuesCheckbox.Checked);
       } else {
-        fcc.TryCancelCalculation();
+        CorrelationCalculator.TryCancelCalculation();
         var correlation = new DoubleMatrix(corr, Content.Dataset.DoubleVariables, Content.Dataset.DoubleVariables);
         UpdateDataView(correlation);
@@ -66,12 +75,11 @@
     }
 
-
-
-    protected override void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
+    protected override void FeatureCorrelation_CalculationFinished(object sender, AbstractFeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
       if (InvokeRequired) {
-        Invoke(new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished), sender, e);
+        Invoke(new AbstractFeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(FeatureCorrelation_CalculationFinished), sender, e);
         return;
       }
-      correlationCache.SetCorrelation(e.Calculcator, e.Partition, e.Correlation);
+      correlationCache.SetCorrelation(e.Calculcator, e.Partition, e.IgnoreMissingValues, e.Correlation);
+
       var correlation = new DoubleMatrix(e.Correlation, Content.Dataset.DoubleVariables, Content.Dataset.DoubleVariables);
       UpdateDataView(correlation);
@@ -80,5 +88,5 @@
     [NonDiscoverableType]
     private class FeatureCorrelationCache : Object {
-      private Dictionary<Tuple<IDependencyCalculator, string>, double[,]> correlationsCache;
+      private Dictionary<Tuple<IDependencyCalculator, string, bool>, double[,]> correlationsCache;
 
       public FeatureCorrelationCache()
@@ -88,5 +96,5 @@
 
       private void InitializeCaches() {
-        correlationsCache = new Dictionary<Tuple<IDependencyCalculator, string>, double[,]>();
+        correlationsCache = new Dictionary<Tuple<IDependencyCalculator, string, bool>, double[,]>();
       }
 
@@ -95,13 +103,13 @@
       }
 
-      public double[,] GetCorrelation(IDependencyCalculator calc, string partition) {
+      public double[,] GetCorrelation(IDependencyCalculator calc, string partition, bool ignoreMissingValues) {
         double[,] corr;
-        var key = new Tuple<IDependencyCalculator, string>(calc, partition);
+        var key = Tuple.Create(calc, partition, ignoreMissingValues);
         correlationsCache.TryGetValue(key, out corr);
         return corr;
       }
 
-      public void SetCorrelation(IDependencyCalculator calc, string partition, double[,] correlation) {
-        var key = new Tuple<IDependencyCalculator, string>(calc, partition);
+      public void SetCorrelation(IDependencyCalculator calc, string partition, bool ignoreMissingValues, double[,] correlation) {
+        var key = Tuple.Create(calc, partition, ignoreMissingValues);
         correlationsCache[key] = correlation;
       }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs	(revision 13948)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationCalculator.cs	(revision 13948)
@@ -0,0 +1,103 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  public class TimeframeFeatureCorrelationCalculator : AbstractFeatureCorrelationCalculator {
+    public TimeframeFeatureCorrelationCalculator() : base() { }
+
+    // returns true if any calculation takes place
+    public bool CalculateTimeframeElements(IDataAnalysisProblemData problemData, IDependencyCalculator calc, string partition, string variable, int frames, double[,] correlation = null) {
+      if (correlation != null && correlation.GetLength(1) > frames) return false;
+
+      var indices = GetRelevantIndices(problemData, partition);
+      var info = new BackgroundWorkerInfo {
+        Dataset = problemData.Dataset, Calculator = calc, Partition = partition, Indices = indices, Variable = variable, Frames = frames, AlreadyCalculated = correlation
+      };
+
+      StartCalculation(info);
+      return true;
+    }
+
+    protected override void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) {
+      BackgroundWorker worker = (BackgroundWorker)sender;
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
+
+      var dataset = bwInfo.Dataset;
+      var indices = bwInfo.Indices.ToArray();
+      IDependencyCalculator calc = bwInfo.Calculator;
+      string variable = bwInfo.Variable;
+      int frames = bwInfo.Frames;
+      double[,] alreadyCalculated = bwInfo.AlreadyCalculated;
+
+      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
+      int length = doubleVariableNames.Count;
+      double[,] elements = new double[length, frames + 1];
+      double calculations = (frames + 1) * length;
+
+      worker.ReportProgress(0);
+
+      int start = 0;
+      if (alreadyCalculated != null) {
+        for (int i = 0; i < alreadyCalculated.GetLength(0); i++) {
+          Array.Copy(alreadyCalculated, i * alreadyCalculated.GetLength(1), elements, i * elements.GetLength(1), alreadyCalculated.GetLength(1));
+        }
+        start = alreadyCalculated.GetLength(1);
+      }
+
+      for (int i = 0; i < length; i++) {
+        for (int j = start; j <= frames; j++) {
+          if (worker.CancellationPending) {
+            worker.ReportProgress(100);
+            e.Cancel = true;
+            return;
+          }
+
+          IEnumerable<double> var1 = dataset.GetDoubleValues(variable, indices);
+          IEnumerable<double> var2 = dataset.GetDoubleValues(doubleVariableNames[i], indices);
+
+          var valuesInFrame = var1.Take(j);
+          var help = var1.Skip(j).ToList();
+          help.AddRange(valuesInFrame);
+          var1 = help;
+
+          var error = OnlineCalculatorError.None;
+          elements[i, j] = calc.Calculate(var1, var2, out error);
+
+          if (!error.Equals(OnlineCalculatorError.None)) {
+            elements[i, j] = double.NaN;
+          }
+          worker.ReportProgress((int)((100.0 / calculations) * (i * (frames + 1) + j + 1)));
+        }
+      }
+      e.Result = elements;
+      worker.ReportProgress(100);
+    }
+  }
+}
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs	(revision 13948)
@@ -36,6 +36,13 @@
     private string lastFramesValue;
 
+    private new TimeframeFeatureCorrelationCalculator CorrelationCalculator {
+      get { return (TimeframeFeatureCorrelationCalculator)base.CorrelationCalculator; }
+      set { base.CorrelationCalculator = value; }
+    }
+
+
     public TimeframeFeatureCorrelationView() {
       InitializeComponent();
+      CorrelationCalculator = new TimeframeFeatureCorrelationCalculator();
       correlationTimeframCache = new FeatureCorrelationTimeframeCache();
       errorProvider.SetIconAlignment(timeframeTextbox, ErrorIconAlignment.MiddleRight);
@@ -93,30 +100,31 @@
 
     protected override void CalculateCorrelation() {
-      if (correlationCalcComboBox.SelectedItem != null && partitionComboBox.SelectedItem != null
-        && variableSelectionComboBox.SelectedItem != null) {
-        string variable = (string)variableSelectionComboBox.SelectedItem;
-        IDependencyCalculator calc = (IDependencyCalculator)correlationCalcComboBox.SelectedValue;
-        string partition = (string)partitionComboBox.SelectedValue;
-        int frames;
-        int.TryParse(timeframeTextbox.Text, out frames);
-        dataView.Enabled = false;
-        double[,] corr = correlationTimeframCache.GetTimeframeCorrelation(calc, partition, variable);
-        if (corr == null) {
-          fcc.CalculateTimeframeElements(calc, partition, variable, frames);
-        } else if (corr.GetLength(1) <= frames) {
-          fcc.CalculateTimeframeElements(calc, partition, variable, frames, corr);
-        } else {
-          fcc.TryCancelCalculation();
-          var columnNames = Enumerable.Range(0, corr.GetLength(1)).Select(x => x.ToString());
-          var correlation = new DoubleMatrix(corr, columnNames, Content.Dataset.DoubleVariables);
-          ((IStringConvertibleMatrix)correlation).Columns = frames + 1;
-          UpdateDataView(correlation);
-        }
+      if (correlationCalcComboBox.SelectedItem == null) return;
+      if (partitionComboBox.SelectedItem == null) return;
+      if (variableSelectionComboBox.SelectedItem == null) return;
+
+      string variable = (string)variableSelectionComboBox.SelectedItem;
+      IDependencyCalculator calc = (IDependencyCalculator)correlationCalcComboBox.SelectedValue;
+      string partition = (string)partitionComboBox.SelectedValue;
+      int frames;
+      int.TryParse(timeframeTextbox.Text, out frames);
+      dataView.Enabled = false;
+      double[,] corr = correlationTimeframCache.GetTimeframeCorrelation(calc, partition, variable);
+      if (corr == null) {
+        CorrelationCalculator.CalculateTimeframeElements(Content, calc, partition, variable, frames);
+      } else if (corr.GetLength(1) <= frames) {
+        CorrelationCalculator.CalculateTimeframeElements(Content, calc, partition, variable, frames, corr);
+      } else {
+        CorrelationCalculator.TryCancelCalculation();
+        var columnNames = Enumerable.Range(0, corr.GetLength(1)).Select(x => x.ToString());
+        var correlation = new DoubleMatrix(corr, columnNames, Content.Dataset.DoubleVariables);
+        ((IStringConvertibleMatrix)correlation).Columns = frames + 1;
+        UpdateDataView(correlation);
       }
     }
 
-    protected override void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
+    protected override void FeatureCorrelation_CalculationFinished(object sender, AbstractFeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
       if (InvokeRequired) {
-        Invoke(new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished), sender, e);
+        Invoke(new AbstractFeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(FeatureCorrelation_CalculationFinished), sender, e);
       } else {
         correlationTimeframCache.SetTimeframeCorrelation(e.Calculcator, e.Partition, e.Variable, e.Correlation);
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 13948)
@@ -206,4 +206,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationCalculator.cs" />
+    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationCalculator.cs" />
     <Compile Include="Classification\ClassificationEnsembleSolutionEstimatedClassValuesView.cs">
       <SubType>UserControl</SubType>
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionTargetResponseGradientView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionTargetResponseGradientView.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionTargetResponseGradientView.cs	(revision 13948)
@@ -149,5 +149,5 @@
         variableListView.Items.Add(key: variable, text: variable, imageIndex: 0);
 
-      foreach (var variable in Content.GetUsedVariablesForPrediction())
+      foreach (var variable in Content.Model.VariablesUsedForPrediction)
         variableListView.Items[variable].Checked = true;
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 13948)
@@ -67,5 +67,5 @@
       this.btnImpactCalculation.UseVisualStyleBackColor = true;
       this.btnImpactCalculation.Click += new System.EventHandler(this.btnImpactCalculation_Click);
-      this.toolTip.SetToolTip(this.btnImpactCalculation, "Simplify solution");
+      this.toolTip.SetToolTip(this.btnImpactCalculation, "Calculate impacts");
       // 
       // flowLayoutPanel
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 13948)
@@ -43,4 +43,9 @@
     }
 
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      btnImpactCalculation.Enabled = Content != null && !Locked;
+    }
+
     protected virtual void btnImpactCalculation_Click(object sender, EventArgs e) {
       var mainForm = (MainForm.WindowsForms.MainForm)MainFormManager.MainForm;
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 13948)
@@ -182,8 +182,10 @@
     <Compile Include="Implementation\Classification\ConstantClassificationSolution.cs" />
     <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolutionBase.cs" />
+    <Compile Include="Implementation\Classification\ClassificationModel.cs" />
     <Compile Include="Implementation\Clustering\ClusteringProblem.cs" />
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
     <Compile Include="Implementation\ConstantModel.cs" />
+    <Compile Include="Implementation\DataAnalysisModel.cs" />
     <Compile Include="Implementation\Regression\ConfidenceBoundRegressionSolution.cs" />
     <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
@@ -194,4 +196,5 @@
     </Compile>
     <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
+    <Compile Include="Implementation\Regression\RegressionModel.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionVariableImpactsCalculator.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\Models\ConstantTimeSeriesPrognosisModel.cs" />
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 13948)
@@ -32,5 +32,8 @@
   [StorableClass]
   [Item("ClassificationEnsembleModel", "A classification model that contains an ensemble of multiple classification models")]
-  public class ClassificationEnsembleModel : NamedItem, IClassificationEnsembleModel {
+  public class ClassificationEnsembleModel : ClassificationModel, IClassificationEnsembleModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
+    }
 
     [Storable]
@@ -49,8 +52,10 @@
     public ClassificationEnsembleModel() : this(Enumerable.Empty<IClassificationModel>()) { }
     public ClassificationEnsembleModel(IEnumerable<IClassificationModel> models)
-      : base() {
+      : base(string.Empty) {
       this.name = ItemName;
       this.description = ItemDescription;
       this.models = new List<IClassificationModel>(models);
+
+      if (this.models.Any()) this.TargetVariable = this.models.First().TargetVariable;
     }
 
@@ -59,10 +64,11 @@
     }
 
-    #region IClassificationEnsembleModel Members
     public void Add(IClassificationModel model) {
+      if (string.IsNullOrEmpty(TargetVariable)) TargetVariable = model.TargetVariable;
       models.Add(model);
     }
     public void Remove(IClassificationModel model) {
       models.Remove(model);
+      if (!models.Any()) TargetVariable = string.Empty;
     }
 
@@ -78,9 +84,6 @@
     }
 
-    #endregion
 
-    #region IClassificationModel Members
-
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       foreach (var estimatedValuesVector in GetEstimatedClassValueVectors(dataset, rows)) {
         // return the class which is most often occuring
@@ -94,8 +97,9 @@
     }
 
-    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
       return new ClassificationEnsembleSolution(models, new ClassificationEnsembleProblemData(problemData));
     }
-    #endregion
+
+
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs	(revision 13948)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationModel.cs	(revision 13948)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Classification Model", "Base class for all classification models.")]
+  public abstract class ClassificationModel : DataAnalysisModel, IClassificationModel {
+    [Storable]
+    private string targetVariable;
+    public string TargetVariable {
+      get { return targetVariable; }
+      protected set { targetVariable = value; }
+    }
+
+    protected ClassificationModel(bool deserializing) : base(deserializing) { }
+    protected ClassificationModel(ClassificationModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.targetVariable = original.targetVariable;
+    }
+
+    protected ClassificationModel(string targetVariable)
+      : base("Classification Model") {
+      this.targetVariable = targetVariable;
+    }
+    protected ClassificationModel(string targetVariable, string name)
+      : base(name) {
+      this.targetVariable = targetVariable;
+    }
+    protected ClassificationModel(string targetVariable, string name, string description)
+      : base(name, description) {
+      this.targetVariable = targetVariable;
+    }
+
+    public abstract IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows);
+    public abstract IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
+  }
+}
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 13948)
@@ -33,5 +33,9 @@
   [StorableClass]
   [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
-  public class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
+  public class DiscriminantFunctionClassificationModel : ClassificationModel, IDiscriminantFunctionClassificationModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return model.VariablesUsedForPrediction; }
+    }
+
     [Storable]
     private IRegressionModel model;
@@ -73,7 +77,8 @@
 
     public DiscriminantFunctionClassificationModel(IRegressionModel model, IDiscriminantFunctionThresholdCalculator thresholdCalculator)
-      : base() {
+      : base(model.TargetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
+
       this.model = model;
       this.classValues = new double[0];
@@ -115,5 +120,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
       if (!Thresholds.Any() && !ClassValues.Any()) throw new ArgumentException("No thresholds and class values were set for the current classification model.");
       foreach (var x in GetEstimatedValues(dataset, rows)) {
@@ -135,10 +140,10 @@
     #endregion
 
-    public virtual IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData) {
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return CreateDiscriminantFunctionClassificationSolution(problemData);
+    }
+    public virtual IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(
+      IClassificationProblemData problemData) {
       return new DiscriminantFunctionClassificationSolution(this, new ClassificationProblemData(problemData));
-    }
-
-    public virtual IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
-      return CreateDiscriminantFunctionClassificationSolution(problemData);
     }
   }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/ConstantModel.cs	(revision 13948)
@@ -31,7 +31,10 @@
   [StorableClass]
   [Item("Constant Model", "A model that always returns the same constant value regardless of the presented input data.")]
-  public class ConstantModel : NamedItem, IRegressionModel, IClassificationModel, ITimeSeriesPrognosisModel, IStringConvertibleValue {
+  public class ConstantModel : RegressionModel, IClassificationModel, ITimeSeriesPrognosisModel, IStringConvertibleValue {
+    public override IEnumerable<string> VariablesUsedForPrediction { get { return Enumerable.Empty<string>(); } }
+
+
     [Storable]
-    private double constant;
+    private readonly double constant;
     public double Constant {
       get { return constant; }
@@ -45,8 +48,9 @@
       this.constant = original.constant;
     }
+
     public override IDeepCloneable Clone(Cloner cloner) { return new ConstantModel(this, cloner); }
 
-    public ConstantModel(double constant)
-      : base() {
+    public ConstantModel(double constant, string targetVariable = "Target")
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
@@ -55,5 +59,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return rows.Select(row => Constant);
     }
@@ -65,5 +69,5 @@
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new ConstantRegressionSolution(this, new RegressionProblemData(problemData));
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs	(revision 13948)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisModel.cs	(revision 13948)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("DataAnalysisModel", "Base class for data analysis models.")]
+  public abstract class DataAnalysisModel : NamedItem, IDataAnalysisModel {
+    [StorableConstructor]
+    protected DataAnalysisModel(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisModel(DataAnalysisModel original, Cloner cloner)
+      : base(original, cloner) { }
+    protected DataAnalysisModel() { }
+    protected DataAnalysisModel(string name) : base(name) { }
+    protected DataAnalysisModel(string name, string description) : base(name, description) { }
+
+    public abstract IEnumerable<string> VariablesUsedForPrediction { get; }
+  }
+}
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 13948)
@@ -1,5 +1,5 @@
 #region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -111,8 +111,4 @@
     protected override void DeregisterItemEvents(IEnumerable<IResult> items) { }
 
-    public virtual IEnumerable<string> GetUsedVariablesForPrediction() {
-      return this.ProblemData.AllowedInputVariables;
-    }
-
     #region INamedItem Members
     [Storable]
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 13948)
@@ -32,5 +32,7 @@
   [Item("Constant Regression Model", "A model that always returns the same constant value regardless of the presented input data.")]
   [Obsolete]
-  public class ConstantRegressionModel : NamedItem, IRegressionModel, IStringConvertibleValue {
+  public class ConstantRegressionModel : RegressionModel, IStringConvertibleValue {
+    public override IEnumerable<string> VariablesUsedForPrediction { get { return Enumerable.Empty<string>(); } }
+
     [Storable]
     private double constant;
@@ -46,8 +48,9 @@
       this.constant = original.constant;
     }
+
     public override IDeepCloneable Clone(Cloner cloner) { return new ConstantRegressionModel(this, cloner); }
 
-    public ConstantRegressionModel(double constant)
-      : base() {
+    public ConstantRegressionModel(double constant, string targetVariable = "Target")
+      : base(targetVariable) {
       this.name = ItemName;
       this.description = ItemDescription;
@@ -56,9 +59,9 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       return rows.Select(row => Constant);
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new ConstantRegressionSolution(new ConstantModel(constant), new RegressionProblemData(problemData));
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 13948)
@@ -33,5 +33,8 @@
   [StorableClass]
   [Item("RegressionEnsembleModel", "A regression model that contains an ensemble of multiple regression models")]
-  public sealed class RegressionEnsembleModel : NamedItem, IRegressionEnsembleModel {
+  public sealed class RegressionEnsembleModel : RegressionModel, IRegressionEnsembleModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
+    }
 
     private List<IRegressionModel> models;
@@ -100,17 +103,21 @@
     public RegressionEnsembleModel(IEnumerable<IRegressionModel> models) : this(models, models.Select(m => 1.0)) { }
     public RegressionEnsembleModel(IEnumerable<IRegressionModel> models, IEnumerable<double> modelWeights)
-      : base() {
+      : base(string.Empty) {
       this.name = ItemName;
       this.description = ItemDescription;
 
-
       this.models = new List<IRegressionModel>(models);
       this.modelWeights = new List<double>(modelWeights);
+
+      if (this.models.Any()) this.TargetVariable = this.models.First().TargetVariable;
     }
 
     public void Add(IRegressionModel model) {
+      if (string.IsNullOrEmpty(TargetVariable)) TargetVariable = model.TargetVariable;
       Add(model, 1.0);
     }
     public void Add(IRegressionModel model, double weight) {
+      if (string.IsNullOrEmpty(TargetVariable)) TargetVariable = model.TargetVariable;
+
       models.Add(model);
       modelWeights.Add(weight);
@@ -122,4 +129,6 @@
     }
     public void AddRange(IEnumerable<IRegressionModel> models, IEnumerable<double> weights) {
+      if (string.IsNullOrEmpty(TargetVariable)) TargetVariable = models.First().TargetVariable;
+
       this.models.AddRange(models);
       modelWeights.AddRange(weights);
@@ -131,4 +140,6 @@
       models.RemoveAt(index);
       modelWeights.RemoveAt(index);
+
+      if (!models.Any()) TargetVariable = string.Empty;
       OnChanged();
     }
@@ -139,4 +150,6 @@
         modelWeights.RemoveAt(index);
       }
+
+      if (!models.Any()) TargetVariable = string.Empty;
       OnChanged();
     }
@@ -165,5 +178,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       double weightsSum = modelWeights.Sum();
       var summedEstimates = from estimatedValuesVector in GetEstimatedValueVectors(dataset, rows)
@@ -213,9 +226,6 @@
 
 
-    public RegressionEnsembleSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionEnsembleSolution(this, new RegressionEnsembleProblemData(problemData));
-    }
-    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
-      return CreateRegressionSolution(problemData);
     }
   }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs	(revision 13948)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionModel.cs	(revision 13948)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Regression Model", "Base class for all regression models.")]
+  public abstract class RegressionModel : DataAnalysisModel, IRegressionModel {
+    [Storable]
+    private string targetVariable;
+    public string TargetVariable {
+      get { return targetVariable; }
+      protected set { targetVariable = value; }
+    }
+
+    protected RegressionModel(bool deserializing) : base(deserializing) { }
+
+    protected RegressionModel(RegressionModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.targetVariable = original.targetVariable;
+    }
+
+    protected RegressionModel(string targetVariable)
+      : base("Regression Model") {
+      this.targetVariable = targetVariable;
+    }
+    protected RegressionModel(string targetVariable, string name)
+      : base(name) {
+      this.targetVariable = targetVariable;
+    }
+    protected RegressionModel(string targetVariable, string name, string description)
+      : base(name, description) {
+      this.targetVariable = targetVariable;
+    }
+
+    public abstract IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows);
+    public abstract IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData);
+  }
+}
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 13948)
@@ -30,11 +30,13 @@
   [StorableClass]
   [Item("Autoregressive TimeSeries Model", "A linear autoregressive time series model used to predict future values.")]
-  public class TimeSeriesPrognosisAutoRegressiveModel : NamedItem, ITimeSeriesPrognosisModel {
+  public class TimeSeriesPrognosisAutoRegressiveModel : RegressionModel, ITimeSeriesPrognosisModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return Enumerable.Empty<string>(); } // what to return here?
+    }
+
     [Storable]
     public double[] Phi { get; private set; }
     [Storable]
     public double Constant { get; private set; }
-    [Storable]
-    public string TargetVariable { get; private set; }
 
     public int TimeOffset { get { return Phi.Length; } }
@@ -46,5 +48,4 @@
       this.Phi = (double[])original.Phi.Clone();
       this.Constant = original.Constant;
-      this.TargetVariable = original.TargetVariable;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -52,8 +53,7 @@
     }
     public TimeSeriesPrognosisAutoRegressiveModel(string targetVariable, double[] phi, double constant)
-      : base("AR(1) Model") {
+      : base(targetVariable, "AR(1) Model") {
       Phi = (double[])phi.Clone();
       Constant = constant;
-      TargetVariable = targetVariable;
     }
 
@@ -91,5 +91,5 @@
     }
 
-    public IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
+    public override IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows) {
       var targetVariables = dataset.GetReadOnlyDoubleValues(TargetVariable);
       foreach (int row in rows) {
@@ -111,5 +111,5 @@
       return new TimeSeriesPrognosisSolution(this, new TimeSeriesPrognosisProblemData(problemData));
     }
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       throw new NotSupportedException();
     }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 13948)
@@ -25,4 +25,5 @@
     IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows);
     IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
+    string TargetVariable { get; }
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 13948)
@@ -20,8 +20,10 @@
 #endregion
 
+using System.Collections.Generic;
 using HeuristicLab.Core;
 
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IDataAnalysisModel : INamedItem {
+    IEnumerable<string> VariablesUsedForPrediction { get; }
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 13948)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +28,4 @@
     IDataAnalysisModel Model { get; }
     IDataAnalysisProblemData ProblemData { get; set; }
-    IEnumerable<string> GetUsedVariablesForPrediction();
 
     event EventHandler ModelChanged;
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 13948)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 
@@ -29,4 +30,5 @@
 
     double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState);
+    double Calculate(IEnumerable<Tuple<double, double>> values, out OnlineCalculatorError errorState);
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 13948)
@@ -25,4 +25,5 @@
     IEnumerable<double> GetEstimatedValues(IDataset dataset, IEnumerable<int> rows);
     IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData);
+    string TargetVariable { get; }
   }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 13948)
@@ -41,4 +41,8 @@
       if (errorState != OnlineCalculatorError.None) return double.NaN;
       return d;
+    }
+
+    public double Calculate(IEnumerable<Tuple<double, double>> values, out OnlineCalculatorError errorState) {
+      return HoeffD(values.Select(v => v.Item1), values.Select(v => v.Item2), out errorState);
     }
 
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 13948)
@@ -35,4 +35,14 @@
       return OnlinePearsonsRCalculator.Calculate(originalValues, estimatedValues, out errorState);
     }
+
+    public double Calculate(IEnumerable<Tuple<double, double>> values, out OnlineCalculatorError errorState) {
+      var calculator = new OnlinePearsonsRCalculator();
+      foreach (var tuple in values) {
+        calculator.Add(tuple.Item1, tuple.Item2);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+      errorState = calculator.ErrorState;
+      return calculator.R;
+    }
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 13948)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 
@@ -35,4 +36,15 @@
       return r * r;
     }
+
+    public double Calculate(IEnumerable<Tuple<double, double>> values, out OnlineCalculatorError errorState) {
+      var calculator = new OnlinePearsonsRCalculator();
+      foreach (var tuple in values) {
+        calculator.Add(tuple.Item1, tuple.Item2);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+      errorState = calculator.ErrorState;
+      var r = calculator.R;
+      return r * r;
+    }
   }
 }
Index: /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs
===================================================================
--- /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 13947)
+++ /branches/HeuristicLab.RegressionSolutionGradientView/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 13948)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -33,5 +34,8 @@
 
     public double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
-      return SpearmansRankCorrelationCoefficientCalculator.CalculateSpearmansRank(originalValues, estimatedValues, out errorState);
+      return CalculateSpearmansRank(originalValues, estimatedValues, out errorState);
+    }
+    public double Calculate(IEnumerable<Tuple<double, double>> values, out OnlineCalculatorError errorState) {
+      return CalculateSpearmansRank(values.Select(v => v.Item1), values.Select(v => v.Item2), out errorState);
     }
 
@@ -50,4 +54,6 @@
       return rs;
     }
+
+
   }
 }
