Index: branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln	(revision 5601)
@@ -85,4 +85,5 @@
 		{DF87C13E-A889-46FF-8153-66DCAA8C5674} = {DF87C13E-A889-46FF-8153-66DCAA8C5674}
 		{3D28463F-EC96-4D82-AFEE-38BE91A0CA00} = {3D28463F-EC96-4D82-AFEE-38BE91A0CA00}
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198} = {3E9E8944-44FF-40BB-A622-3A4A7DD0F198}
 		{678E2145-8152-4E19-9646-07D439D00301} = {678E2145-8152-4E19-9646-07D439D00301}
 		{49F28045-7B5F-411B-8D59-16C846FA26E0} = {49F28045-7B5F-411B-8D59-16C846FA26E0}
@@ -373,4 +374,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Symbolic.Tests-3.4", "HeuristicLab.Problems.DataAnalysis.Symbolic\3.4\Tests\HeuristicLab.Problems.DataAnalysis.Symbolic.Tests-3.4.csproj", "{2A976109-67B9-4FF0-89DE-A26A8307A1CE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Views-3.4", "HeuristicLab.Problems.DataAnalysis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj", "{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}"
 EndProject
 Global
@@ -1719,4 +1722,16 @@
 		{2A976109-67B9-4FF0-89DE-A26A8307A1CE}.Release|x86.ActiveCfg = Release|x86
 		{2A976109-67B9-4FF0-89DE-A26A8307A1CE}.Release|x86.Build.0 = Release|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x64.ActiveCfg = Debug|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x64.Build.0 = Debug|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x86.ActiveCfg = Debug|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x86.Build.0 = Debug|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x64.ActiveCfg = Release|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x64.Build.0 = Release|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x86.ActiveCfg = Release|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/DataAnalysis Refactoring/HeuristicLab.Parameters/3.3/OptionalValueParameter.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Parameters/3.3/OptionalValueParameter.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Parameters/3.3/OptionalValueParameter.cs	(revision 5601)
@@ -92,7 +92,9 @@
         if (value != reactOnValueToStringChangedAndValueItemImageChanged) {
           reactOnValueToStringChangedAndValueItemImageChanged = value;
-          if (reactOnValueToStringChangedAndValueItemImageChanged)
+          if (reactOnValueToStringChangedAndValueItemImageChanged) {
             RegisterValueEvents();
-          else
+            OnToStringChanged();
+            OnItemImageChanged();
+          } else
             DeregisterValueEvents();
         }
@@ -187,5 +189,5 @@
       ((IValueParameter)this).Value = value;
     }
-    
+
     public event EventHandler ValueChanged;
     protected virtual void OnValueChanged() {
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectiveMeanSquaredErrorTreeSizeEvaluator.cs	(revision 5601)
@@ -53,5 +53,5 @@
     public static double[] Calculate(ISymbolicDataAnalysisTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable.Value, rows);
+      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable, rows);
       IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
       double mse = OnlineMeanSquaredErrorEvaluator.Calculate(originalValues, boundedEstimationValues);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/MultiObjective/SymbolicRegressionMultiObjectivePearsonRSquaredTreeSizeEvaluator.cs	(revision 5601)
@@ -53,5 +53,5 @@
     public static double[] Calculate(ISymbolicDataAnalysisTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable.Value, rows);
+      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable, rows);
       double r2 = OnlinePearsonsRSquaredEvaluator.Calculate(originalValues, estimatedValues);
       return new double[2] { r2, solution.Length };
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 5601)
@@ -53,5 +53,5 @@
     public static double Calculate(ISymbolicDataAnalysisTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable.Value, rows);
+      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable, rows);
       IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
       return OnlineMeanSquaredErrorEvaluator.Calculate(originalValues, boundedEstimationValues);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SingleObjective/SymbolicRegressionSingleObjectivePearsonRSquaredEvaluator.cs	(revision 5601)
@@ -53,5 +53,5 @@
     public static double Calculate(ISymbolicDataAnalysisTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, IRegressionProblemData problemData, IEnumerable<int> rows) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable.Value, rows);
+      IEnumerable<double> originalValues = problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable, rows);
       return OnlinePearsonsRSquaredEvaluator.Calculate(originalValues, estimatedValues);
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/ClassificationProblemData.cs	(revision 5601)
@@ -22,11 +22,20 @@
 using System;
 using System.Collections.Generic;
+using System.IO;
 using System.Linq;
 using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis {
   [StorableClass]
+  [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
   public class ClassificationProblemData : DataAnalysisProblemData, IClassificationProblemData {
+    private const string TargetVariableParameterName = "TargetVariable";
+    private const string ClassNamesParameterName = "ClassNames";
+    private const string ClassificationPenaltiesParameterName = "ClassificationPenalties";
+
     #region default data
     private static string[] defaultVariableNames = new string[] { "sample", "clump thickness", "cell size", "cell shape", "marginal adhesion", "epithelial cell size", "bare nuclei", "chromatin", "nucleoli", "mitoses", "class" };
@@ -173,105 +182,125 @@
     #endregion
 
+    #region parameter properties
+    public IValueParameter<StringValue> TargetVariableParameter {
+      get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+    public IFixedValueParameter<StringMatrix> ClassNamesParameter {
+      get { return (IFixedValueParameter<StringMatrix>)Parameters[ClassNamesParameterName]; }
+    }
+    public IFixedValueParameter<DoubleMatrix> ClassificationPenaltiesParameter {
+      get { return (IFixedValueParameter<DoubleMatrix>)Parameters[ClassificationPenaltiesParameterName]; }
+    }
+    #endregion
+
     #region propeties
-    [Storable]
-    private string targetVariable;
     public string TargetVariable {
-      get { return targetVariable; }
-      set {
-        if (!Dataset.VariableNames.Contains(value))
-          throw new ArgumentException(string.Format("The target variable {0} is not present in the dataset", value));
-        if (targetVariable != value) {
-          targetVariable = value;
-
-          InitializeTargetVariableDependentMembers();
-          OnChanged();
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    private List<double> classValues;
+    public List<double> ClassValues {
+      get {
+        if (classValues == null) {
+          classValues = Dataset.GetEnumeratedVariableValues(TargetVariableParameter.Value.Value).Distinct().ToList();
+          classValues.Sort();
+        }
+        return classValues;
+      }
+    }
+    IEnumerable<double> IClassificationProblemData.ClassValues {
+      get { return ClassValues; }
+    }
+
+    public int Classes {
+      get { return ClassValues.Count; }
+    }
+
+    private List<string> classNames;
+    public List<string> ClassNames {
+      get {
+        if (classNames == null) {
+          classNames = new List<string>();
+          for (int i = 0; i < ClassNamesParameter.Value.Rows; i++)
+            classNames.Add(ClassNamesParameter.Value[i, 0]);
+        }
+        return classNames;
+      }
+    }
+    IEnumerable<string> IClassificationProblemData.ClassNames {
+      get { return ClassNames; }
+    }
+
+    private Dictionary<Tuple<double, double>, double> classificationPenaltiesCache = new Dictionary<Tuple<double, double>, double>();
+    #endregion
+
+
+    [StorableConstructor]
+    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+    protected ClassificationProblemData(ClassificationProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblemData(this, cloner); }
+
+    public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
+    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables) {
+      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
+      Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, "", new StringMatrix()));
+      Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, "", new DoubleMatrix()));
+
+      ResetTargetVariableDependentMembers();
+      RegisterParameterEvents();
+    }
+
+    private void ResetTargetVariableDependentMembers() {
+      DergisterParameterEvents();
+
+      classNames = null;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Columns = 1;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValues.Count;
+      for (int i = 0; i < Classes; i++)
+        ClassNamesParameter.Value[i, 0] = "Class " + ClassValues[i];
+      ClassNamesParameter.Value.ColumnNames = new List<string>() { "ClassNames" };
+      ClassNamesParameter.Value.RowNames = ClassValues.Select(s => "ClassValue: " + s);
+
+      classificationPenaltiesCache.Clear();
+      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Rows = Classes;
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Columns = Classes;
+      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
+      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
+      for (int i = 0; i < Classes; i++) {
+        for (int j = 0; j < Classes; j++) {
+          if (i != j) ClassificationPenaltiesParameter.Value[i, j] = 1;
+          else ClassificationPenaltiesParameter.Value[i, j] = 0;
         }
       }
-    }
-
-    private List<double> classValues;
-    [Storable]
-    public IEnumerable<double> ClassValues {
-      get { return classValues; }
-      private set { classValues = new List<double>(value); }
-    }
-
-    public int Classes {
-      get { return classValues.Count; }
-    }
-
-    private Dictionary<double, string> classValueClassNameMapping;
-    private Dictionary<string, double> classNameClassValueMapping;
-    [Storable(Name = "ClassNames")]
-    private IEnumerable<KeyValuePair<double, string>> classValueClassNameMappingStorable {
-      get { return classValueClassNameMapping; }
-      set {
-        classValueClassNameMapping = new Dictionary<double, string>();
-        foreach (var mapping in value)
-          classValueClassNameMapping[mapping.Key] = mapping.Value;
-
-        classNameClassValueMapping = classValueClassNameMapping.ToDictionary(x => x.Value, x => x.Key);
-      }
-    }
-    public IEnumerable<string> ClassNames {
-      get { return classValueClassNameMapping.Values; }
-    }
-
-    [Storable]
-    private Dictionary<Tuple<double, double>, double> misclassificationMatrix;
-    #endregion
-
-
-    [StorableConstructor]
-    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
-    protected ClassificationProblemData(ClassificationProblemData original, Cloner cloner) : base(original, cloner) { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblemData(this, cloner); }
-
-    public ClassificationProblemData()
-      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
-    }
-
-    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
-      : base(dataset, allowedInputVariables) {
-      TargetVariable = targetVariable;
-
-      InitializeTargetVariableDependentMembers();
-    }
-
-    private void InitializeTargetVariableDependentMembers() {
-      classValues = Dataset.GetEnumeratedVariableValues(targetVariable).Distinct().ToList();
-      classValues.Sort();
-
-      classValueClassNameMapping = new Dictionary<double, string>();
-      foreach (double classValue in ClassValues) {
-        classValueClassNameMapping.Add(classValue, "Class " + classValue);
-      }
-      classNameClassValueMapping = classValueClassNameMapping.ToDictionary(x => x.Value, x => x.Key);
-      OnClassNamesChanged();
-
-      //set default misclassification matrix
-      misclassificationMatrix = new Dictionary<Tuple<double, double>, double>();
-      foreach (double classValue1 in ClassValues) {
-        foreach (double classValue2 in ClassValues) {
-          double penalty = 1.0;
-          if (classValue1 == classValue2) penalty = 0.0;
-          SetClassificationPenalty(classValue1, classValue1, penalty);
-        }
-      }
-      OnClassificationPenaltyChanged();
+      ((ValueParameter<DoubleMatrix>)ClassificationPenaltiesParameter).ReactOnValueToStringChangedAndValueItemImageChanged = true;
+      RegisterParameterEvents();
     }
 
     public string GetClassName(double classValue) {
-      return classValueClassNameMapping[classValue];
+      if (!ClassValues.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValues.IndexOf(classValue);
+      return ClassNames[index];
     }
     public double GetClassValue(string className) {
-      return classNameClassValueMapping[className];
+      if (!ClassNames.Contains(className)) throw new ArgumentException();
+      int index = ClassNames.IndexOf(className);
+      return ClassValues[index];
     }
     public void SetClassName(double classValue, string className) {
       if (!classValues.Contains(classValue)) throw new ArgumentException();
-      if (classValueClassNameMapping[classValue] != className) {
-        classValueClassNameMapping[classValue] = className;
-        classNameClassValueMapping = classValueClassNameMapping.ToDictionary(x => x.Value, x => x.Key);
-      }
+      int index = ClassValues.IndexOf(classValue);
+      ClassNames[index] = className;
+      ClassNamesParameter.Value[index, 0] = className;
     }
 
@@ -281,5 +310,10 @@
     public double GetClassificationPenalty(double correctClassValue, double estimatedClassValue) {
       var key = Tuple.Create(correctClassValue, estimatedClassValue);
-      return misclassificationMatrix[key];
+      if (!classificationPenaltiesCache.ContainsKey(key)) {
+        int correctClassIndex = ClassValues.IndexOf(correctClassValue);
+        int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
+        classificationPenaltiesCache[key] = ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex];
+      }
+      return classificationPenaltiesCache[key];
     }
     public void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty) {
@@ -288,20 +322,52 @@
     public void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty) {
       var key = Tuple.Create(correctClassValue, estimatedClassValue);
-      if (!misclassificationMatrix.ContainsKey(key) || misclassificationMatrix[key] != penalty) {
-        misclassificationMatrix[key] = penalty;
-        OnClassificationPenaltyChanged();
-      }
-    }
-
-    public event EventHandler ClassNamesChanged;
-    protected virtual void OnClassNamesChanged() {
-      var handler = ClassNamesChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
-    public event EventHandler ClassificationPenaltyChanged;
-    protected virtual void OnClassificationPenaltyChanged() {
-      var handler = ClassificationPenaltyChanged;
-      if (handler != null) handler(this, EventArgs.Empty);
-    }
+      int correctClassIndex = ClassValues.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValues.IndexOf(estimatedClassValue);
+
+      ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex] = penalty;
+    }
+
+    #region events
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassificationPenaltiesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+    }
+    private void DergisterParameterEvents() {
+      TargetVariableParameter.ValueChanged -= new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+      ClassificationPenaltiesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(MatrixParameter_ItemChanged);
+    }
+
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      classValues = null;
+      ResetTargetVariableDependentMembers();
+      OnChanged();
+    }
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+    private void MatrixParameter_ItemChanged(object sender, EventArgs<int, int> e) {
+      OnChanged();
+    }
+    #endregion
+
+    #region Import from file
+    public static ClassificationProblemData ImportFromFile(string fileName) {
+      TableFileParser csvFileParser = new TableFileParser();
+      csvFileParser.Parse(fileName);
+
+      Dataset dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      dataset.Name = Path.GetFileName(fileName);
+
+      ClassificationProblemData problemData = new ClassificationProblemData(dataset, dataset.VariableNames.Skip(1), dataset.VariableNames.First());
+      problemData.Name = "Data imported from " + Path.GetFileName(fileName);
+      return problemData;
+    }
+    #endregion
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblem.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblem.cs	(revision 5601)
@@ -33,5 +33,5 @@
     where T : class, IDataAnalysisProblemData {
     private const string ProblemDataParameterName = "ProblemData";
-    private const string ProblemDataParameterDescription = "";
+    private const string ProblemDataParameterDescription = "The data set, target variable and input variables of the data analysis problem.";
     #region parameter properties
     IParameter IDataAnalysisProblem.ProblemDataParameter {
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/DataAnalysisProblemData.cs	(revision 5601)
@@ -41,6 +41,6 @@
 
     #region parameter properites
-    public IValueParameter<Dataset> DatasetParameter {
-      get { return (IValueParameter<Dataset>)Parameters[DatasetParameterName]; }
+    public IFixedValueParameter<Dataset> DatasetParameter {
+      get { return (IFixedValueParameter<Dataset>)Parameters[DatasetParameterName]; }
     }
     public IFixedValueParameter<ICheckedItemCollection<StringValue>> InputVariablesParameter {
@@ -64,5 +64,4 @@
     public Dataset Dataset {
       get { return DatasetParameter.Value; }
-      set { DatasetParameter.Value = value; }
     }
     public ICheckedItemCollection<StringValue> InputVariables {
@@ -120,5 +119,5 @@
       int testPartitionEnd = dataset.Rows;
 
-      Parameters.Add(new ValueParameter<Dataset>(DatasetParameterName, "", dataset));
+      Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", dataset));
       Parameters.Add(new FixedValueParameter<ICheckedItemCollection<StringValue>>(InputVariablesParameterName, "", inputVariables.AsReadOnly()));
       Parameters.Add(new FixedValueParameter<IntValue>(TrainingPartitionStartParameterName, "", new IntValue(trainingPartitionStart)));
@@ -127,4 +126,5 @@
       Parameters.Add(new FixedValueParameter<IntValue>(TestPartitionEndParameterName, "", new IntValue(testPartitionEnd)));
 
+      ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterEventHandlers();
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 5601)
@@ -20,9 +20,9 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IClassificationProblemData : IDataAnalysisProblemData {
-    string TargetVariable { get; set; }
+    string TargetVariable { get; }
+
     IEnumerable<string> ClassNames { get; }
     IEnumerable<double> ClassValues { get; }
@@ -37,7 +37,4 @@
     void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty);
     void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty);
-
-    event EventHandler ClassNamesChanged;
-    event EventHandler ClassificationPenaltyChanged;
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 5601)
@@ -27,5 +27,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IDataAnalysisProblemData : IParameterizedNamedItem {
-    Dataset Dataset { get; set; }
+    Dataset Dataset { get; }
     ICheckedItemCollection<StringValue> InputVariables { get; }
     IEnumerable<string> AllowedInputVariables { get; }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 5601)
@@ -20,8 +20,7 @@
 #endregion
 
-using HeuristicLab.Data;
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IRegressionProblemData : IDataAnalysisProblemData {
-    StringValue TargetVariable { get; }
+    string TargetVariable { get; }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblemData.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblemData.cs	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis/3.4/RegressionProblemData.cs	(revision 5601)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
 using System.IO;
@@ -31,4 +32,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   [StorableClass]
+  [Item("RegressionProblemData", "Represents an item containing all data defining a regression problem.")]
   public sealed class RegressionProblemData : DataAnalysisProblemData, IRegressionProblemData {
     private const string TargetVariableParameterName = "TargetVariable";
@@ -78,12 +80,20 @@
       get { return (IValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
     }
-    public StringValue TargetVariable {
-      get { return TargetVariableParameter.Value; }
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    [StorableConstructor]
+    private RegressionProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
     }
 
 
-    [StorableConstructor]
-    private RegressionProblemData(bool deserializing) : base(deserializing) { }
-    private RegressionProblemData(RegressionProblemData original, Cloner cloner) : base(original, cloner) { }
+    private RegressionProblemData(RegressionProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
     public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblemData(this, cloner); }
 
@@ -94,7 +104,16 @@
     public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
       : base(dataset, allowedInputVariables) {
-      Parameters.Add(new ConstrainedValueParameter<StringValue>("TargetVariable", new ItemSet<StringValue>(InputVariables), InputVariables.Where(x => x.Value == targetVariable).First()));
+      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
     }
 
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+    }
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+    #region Import from file
     public static RegressionProblemData ImportFromFile(string fileName) {
       TableFileParser csvFileParser = new TableFileParser();
@@ -108,4 +127,5 @@
       return problemData;
     }
+    #endregion
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab/3.3/Files.txt
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab/3.3/Files.txt	(revision 5600)
+++ branches/DataAnalysis Refactoring/HeuristicLab/3.3/Files.txt	(revision 5601)
@@ -62,9 +62,9 @@
 HeuristicLab.Problems.DataAnalysis.Classification.Views\3.3:HeuristicLab.Problems.DataAnalysis.Classification.Views-3.3.dll
 HeuristicLab.Problems.DataAnalysis.Regression\3.3:HeuristicLab.Problems.DataAnalysis.Regression-3.3.dll
-HeuristicLab.Problems.DataAnalysis.Regression\3.4:HeuristicLab.Problems.DataAnalysis.Regression-3.4.dll
 HeuristicLab.Problems.DataAnalysis.Symbolic\3.4:HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll
 HeuristicLab.Problems.DataAnalysis.Symbolic.Classification\3.4:HeuristicLab.Problems.DataAnalysis.Symbolic.Classification-3.4.dll
 HeuristicLab.Problems.DataAnalysis.Symbolic.Regression\3.4:HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll
 HeuristicLab.Problems.DataAnalysis.Views\3.3:HeuristicLab.Problems.DataAnalysis.Views-3.3.dll
+HeuristicLab.Problems.DataAnalysis.Views\3.4:HeuristicLab.Problems.DataAnalysis.Views-3.4.dll
 HeuristicLab.Problems.ExternalEvaluation\3.3:HeuristicLab.Problems.ExternalEvaluation-3.3.dll
 HeuristicLab.Problems.ExternalEvaluation.Views\3.3:HeuristicLab.Problems.ExternalEvaluation.Views-3.3.dll
