Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneR.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/BaselineClassifiers/OneRClassificationModel.cs	(revision 13941)
@@ -31,11 +31,7 @@
   [StorableClass]
   [Item("OneR Classification Model", "A model that uses intervals for one variable to determine the class.")]
-  public class OneRClassificationModel : NamedItem, IClassificationModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
-      get { return Enumerable.Empty<string>(); }
-    }
-
-    public string TargetVariable {
-      get { return variable; }
+  public class OneRClassificationModel : ClassificationModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return new[] { Variable }; }
     }
 
@@ -74,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.");
@@ -92,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();
@@ -116,5 +112,5 @@
     }
 
-    public IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+    public override IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
       return new OneRClassificationSolution(this, new ClassificationProblemData(problemData));
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GBM/GradientBoostingRegressionAlgorithm.cs	(revision 13941)
@@ -376,5 +376,5 @@
 
       var ensembleModel = new RegressionEnsembleModel(models, coefficients.Take(models.Count)) { AverageModelEstimates = false };
-      var ensembleSolution = ensembleModel.CreateRegressionSolution(problemData);
+      var ensembleSolution = (IRegressionEnsembleSolution)ensembleModel.CreateRegressionSolution(problemData);
       return ensembleSolution;
     }
@@ -443,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;
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/GaussianProcessModel.cs	(revision 13941)
@@ -34,6 +34,6 @@
   [StorableClass]
   [Item("GaussianProcessModel", "Represents a Gaussian process posterior.")]
-  public sealed class GaussianProcessModel : NamedItem, IGaussianProcessModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
+  public sealed class GaussianProcessModel : RegressionModel, IGaussianProcessModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
@@ -65,9 +65,5 @@
       get { return meanFunction; }
     }
-    [Storable]
-    private string targetVariable;
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -132,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) {
@@ -151,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();
 
@@ -186,5 +180,5 @@
 
       IEnumerable<double> y;
-      y = ds.GetDoubleValues(targetVariable, rows);
+      y = ds.GetDoubleValues(TargetVariable, rows);
 
       int n = x.GetLength(0);
@@ -305,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
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GaussianProcess/StudentTProcessModel.cs	(revision 13941)
@@ -34,6 +34,6 @@
   [StorableClass]
   [Item("StudentTProcessModel", "Represents a Student-t process posterior.")]
-  public sealed class StudentTProcessModel : NamedItem, IGaussianProcessModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
+  public sealed class StudentTProcessModel : RegressionModel, IGaussianProcessModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
@@ -65,9 +65,5 @@
       get { return meanFunction; }
     }
-    [Storable]
-    private string targetVariable;
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
+
     [Storable]
     private string[] allowedInputVariables;
@@ -135,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();
@@ -155,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();
 
@@ -190,5 +184,5 @@
 
       IEnumerable<double> y;
-      y = ds.GetDoubleValues(targetVariable, rows);
+      y = ds.GetDoubleValues(TargetVariable, rows);
 
       int n = x.GetLength(0);
@@ -322,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModel.cs	(revision 13941)
@@ -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,9 +58,5 @@
     #endregion
 
-    public string TargetVariable {
-      get { return models.First().TargetVariable; }
-    }
-
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
     }
@@ -85,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);
@@ -97,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.
@@ -113,5 +109,5 @@
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionSolution(this, (IRegressionProblemData)problemData.Clone());
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/GradientBoostedTreesModelSurrogate.cs	(revision 13941)
@@ -34,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,9 +55,6 @@
     private int maxSize;
 
-    public string TargetVariable {
-      get { return trainingProblemData.TargetVariable; }
-    }
 
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return actualModel.Models.SelectMany(x => x.VariablesUsedForPrediction).Distinct().OrderBy(x => x); }
     }
@@ -83,5 +80,5 @@
     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) {
+      : base(trainingProblemData.TargetVariable, "Gradient boosted tree model", string.Empty) {
       this.trainingProblemData = trainingProblemData;
       this.seed = seed;
@@ -107,10 +104,10 @@
 
     // 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());
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/GradientBoostedTrees/RegressionTreeModel.cs	(revision 13941)
@@ -34,11 +34,7 @@
   [StorableClass]
   [Item("RegressionTreeModel", "Represents a decision tree for regression.")]
-  public sealed class RegressionTreeModel : NamedItem, IRegressionModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
-      get { return Enumerable.Empty<string>(); }
-    }
-
-    public string TargetVariable {
-      get { return string.Empty; }
+  public sealed class RegressionTreeModel : RegressionModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
+      get { return tree.Select(t => t.VarName).Where(v => v != TreeNode.NO_VARIABLE); }
     }
 
@@ -90,5 +86,5 @@
     private TreeNode[] tree;
 
-    #region old storable format 
+    #region old storable format
     // remove with HL 3.4
     [Storable(AllowOneWay = true)]
@@ -167,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;
     }
@@ -194,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];
@@ -208,5 +204,5 @@
     }
 
-    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+    public override IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
       return new RegressionSolution(this, new RegressionProblemData(problemData));
     }
@@ -227,4 +223,5 @@
       }
     }
+
   }
 }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearDiscriminantAnalysis.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearRegression.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassification.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitClassificationSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public MultinomialLogitClassificationSolution(IClassificationProblemData problemData, MultinomialLogitModel logitModel)
+    public MultinomialLogitClassificationSolution( MultinomialLogitModel logitModel,IClassificationProblemData problemData)
       : base(logitModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/MultinomialLogitModel.cs	(revision 13941)
@@ -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,14 +48,8 @@
     }
 
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
 
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
-
-    [Storable]
-    private string targetVariable;
     [Storable]
     private string[] allowedInputVariables;
@@ -72,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();
@@ -90,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);
 
@@ -116,12 +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));
     }
 
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/MctsSymbolicRegression/MctsSymbolicRegressionStatic.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaClassificationSolution.cs	(revision 13941)
@@ -40,5 +40,5 @@
       : base(original, cloner) {
     }
-    public NcaClassificationSolution(IClassificationProblemData problemData, INcaModel ncaModel)
+    public NcaClassificationSolution(INcaModel ncaModel, IClassificationProblemData problemData)
       : base(ncaModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/Nca/NcaModel.cs	(revision 13941)
@@ -30,11 +30,7 @@
   [Item("NCA Model", "")]
   [StorableClass]
-  public class NcaModel : NamedItem, INcaModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
+  public class NcaModel : ClassificationModel, INcaModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
-    }
-
-    public string TargetVariable {
-      get { return targetVariable; }
     }
 
@@ -46,6 +42,4 @@
     [Storable]
     private string[] allowedInputVariables;
-    [Storable]
-    private string targetVariable;
     [Storable]
     private INearestNeighbourModel nnModel;
@@ -59,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();
 
@@ -79,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));
     }
 
@@ -95,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++)
@@ -111,5 +104,5 @@
           .Range(0, transformationMatrix.GetLength(1))
           .Select(x => "X" + x.ToString())
-          .Concat(targetVariable.ToEnumerable()),
+          .Concat(TargetVariable.ToEnumerable()),
         Reduce(dataset, rows));
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassification.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourClassificationSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NearestNeighbourClassificationSolution(IClassificationProblemData problemData, INearestNeighbourModel nnModel)
+    public NearestNeighbourClassificationSolution(INearestNeighbourModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourModel.cs	(revision 13941)
@@ -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,14 +48,8 @@
     }
 
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
 
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
-
-    [Storable]
-    private string targetVariable;
     [Storable]
     private string[] allowedInputVariables;
@@ -99,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();
 
@@ -171,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);
@@ -209,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegression.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NearestNeighbour/NearestNeighbourRegressionSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NearestNeighbourRegressionSolution(IRegressionProblemData problemData, INearestNeighbourModel nnModel)
+    public NearestNeighbourRegressionSolution(INearestNeighbourModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassification.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkClassificationSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkClassificationSolution(IClassificationProblemData problemData, INeuralNetworkModel nnModel)
+    public NeuralNetworkClassificationSolution(INeuralNetworkModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassification.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleClassificationSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkEnsembleClassificationSolution(IClassificationProblemData problemData, INeuralNetworkEnsembleModel nnModel)
+    public NeuralNetworkEnsembleClassificationSolution(INeuralNetworkEnsembleModel nnModel, IClassificationProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 13941)
@@ -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;
@@ -48,9 +48,5 @@
     }
 
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
-
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
@@ -80,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;
@@ -111,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);
 
@@ -137,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegression.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleRegressionSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkEnsembleRegressionSolution(IRegressionProblemData problemData, INeuralNetworkEnsembleModel nnModel)
+    public NeuralNetworkEnsembleRegressionSolution(INeuralNetworkEnsembleModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
       RecalculateResults();
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 13941)
@@ -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,14 +48,8 @@
     }
 
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
 
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
-
-    [Storable]
-    private string targetVariable;
     [Storable]
     private string[] allowedInputVariables;
@@ -82,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)
@@ -88,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)
@@ -119,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);
 
@@ -145,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegression.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkRegressionSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public NeuralNetworkRegressionSolution(IRegressionProblemData problemData, INeuralNetworkModel nnModel)
+    public NeuralNetworkRegressionSolution(INeuralNetworkModel nnModel, IRegressionProblemData problemData)
       : base(nnModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassification.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestClassificationSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public RandomForestClassificationSolution(IClassificationProblemData problemData, IRandomForestModel randomForestModel)
+    public RandomForestClassificationSolution(IRandomForestModel randomForestModel, IClassificationProblemData problemData)
       : base(randomForestModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestModel.cs	(revision 13941)
@@ -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;
@@ -45,19 +45,8 @@
     }
 
-    public IEnumerable<string> VariablesUsedForPrediction {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return originalTrainingData.AllowedInputVariables; }
     }
 
-    public string TargetVariable {
-      get {
-        var regressionProblemData = originalTrainingData as IRegressionProblemData;
-        var classificationProblemData = originalTrainingData as IClassificationProblemData;
-        if (classificationProblemData != null)
-          return classificationProblemData.TargetVariable;
-        if (regressionProblemData != null)
-          return regressionProblemData.TargetVariable;
-        throw new InvalidOperationException("Getting the target variable requires either a regression or a classification problem data.");
-      }
-    }
 
     // instead of storing the data of the model itself
@@ -107,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;
@@ -163,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);
@@ -190,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));
     }
 
@@ -221,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);
     }
 
@@ -258,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegression.cs	(revision 13941)
@@ -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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/RandomForest/RandomForestRegressionSolution.cs	(revision 13941)
@@ -43,5 +43,5 @@
       : base(original, cloner) {
     }
-    public RandomForestRegressionSolution(IRegressionProblemData problemData, IRandomForestModel randomForestModel)
+    public RandomForestRegressionSolution(IRandomForestModel randomForestModel, IRegressionProblemData problemData)
       : base(randomForestModel, problemData) {
     }
Index: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 13941)
@@ -37,12 +37,9 @@
   [StorableClass]
   [Item("SupportVectorMachineModel", "Represents a support vector machine model.")]
-  public sealed class SupportVectorMachineModel : NamedItem, ISupportVectorMachineModel {
-    public IEnumerable<string> VariablesUsedForPrediction {
+  public sealed class SupportVectorMachineModel : ClassificationModel, ISupportVectorMachineModel {
+    public override IEnumerable<string> VariablesUsedForPrediction {
       get { return allowedInputVariables; }
     }
 
-    public string TargetVariable {
-      get { return targetVariable; }
-    }
 
     private svm_model model;
@@ -90,6 +87,4 @@
 
     [Storable]
-    private string targetVariable;
-    [Storable]
     private string[] allowedInputVariables;
     [Storable]
@@ -103,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)
@@ -113,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();
     }
@@ -130,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
@@ -159,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: trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs
===================================================================
--- trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 13922)
+++ trunk/sources/HeuristicLab.Algorithms.DataAnalysis/3.4/TimeSeries/AutoregressiveModeling.cs	(revision 13941)
@@ -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;
