Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblemData.cs	(revision 4457)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblemData.cs	(revision 5275)
@@ -34,10 +34,8 @@
   [StorableClass]
   public class DataAnalysisProblemData : ParameterizedNamedItem, IStorableContent {
-    private bool suppressEvents = false;
-
+    protected bool suppressEvents = false;
     #region IStorableContent Members
     public string Filename { get; set; }
     #endregion
-
     #region default data
     // y = x^4 + x^3 + x^2 + x
@@ -71,6 +69,6 @@
     #endregion
     #region parameter properties
-    public IValueParameter<Dataset> DatasetParameter {
-      get { return (IValueParameter<Dataset>)Parameters["Dataset"]; }
+    public ValueParameter<Dataset> DatasetParameter {
+      get { return (ValueParameter<Dataset>)Parameters["Dataset"]; }
     }
     public IValueParameter<StringValue> TargetVariableParameter {
@@ -92,9 +90,12 @@
       get { return (IValueParameter<IntValue>)Parameters["TestSamplesEnd"]; }
     }
+    public IValueParameter<PercentValue> ValidationPercentageParameter {
+      get { return (IValueParameter<PercentValue>)Parameters["ValidationPercentage"]; }
+    }
     #endregion
 
     #region properties
     public Dataset Dataset {
-      get { return (Dataset)DatasetParameter.Value; }
+      get { return DatasetParameter.Value; }
       set {
         if (value != Dataset) {
@@ -105,5 +106,5 @@
     }
     public StringValue TargetVariable {
-      get { return (StringValue)TargetVariableParameter.Value; }
+      get { return TargetVariableParameter.Value; }
       set {
         if (value != TargetVariableParameter.Value) {
@@ -115,5 +116,5 @@
     }
     public ICheckedItemList<StringValue> InputVariables {
-      get { return (ICheckedItemList<StringValue>)InputVariablesParameter.Value; }
+      get { return InputVariablesParameter.Value; }
       set {
         if (value != InputVariables) {
@@ -125,5 +126,5 @@
     }
     public IntValue TrainingSamplesStart {
-      get { return (IntValue)TrainingSamplesStartParameter.Value; }
+      get { return TrainingSamplesStartParameter.Value; }
       set {
         if (value != TrainingSamplesStart) {
@@ -135,5 +136,5 @@
     }
     public IntValue TrainingSamplesEnd {
-      get { return (IntValue)TrainingSamplesEndParameter.Value; }
+      get { return TrainingSamplesEndParameter.Value; }
       set {
         if (value != TrainingSamplesEnd) {
@@ -145,5 +146,5 @@
     }
     public IntValue TestSamplesStart {
-      get { return (IntValue)TestSamplesStartParameter.Value; }
+      get { return TestSamplesStartParameter.Value; }
       set {
         if (value != TestSamplesStart) {
@@ -155,5 +156,5 @@
     }
     public IntValue TestSamplesEnd {
-      get { return (IntValue)TestSamplesEndParameter.Value; }
+      get { return TestSamplesEndParameter.Value; }
       set {
         if (value != TestSamplesEnd) {
@@ -164,6 +165,37 @@
       }
     }
-    #endregion
-
+    public PercentValue ValidationPercentage {
+      get { return ValidationPercentageParameter.Value; }
+      set {
+        if (value != ValidationPercentage) {
+          if (value == null) throw new ArgumentNullException();
+          if (value.Value < 0 || value.Value > 1) throw new ArgumentException("ValidationPercentage must be between 0 and 1.");
+          if (ValidationPercentage != null) DeregisterValueTypeEventHandlers(ValidationPercentage);
+          ValidationPercentageParameter.Value = value;
+        }
+      }
+    }
+
+    public IEnumerable<int> TrainingIndizes {
+      get {
+        return Enumerable.Range(TrainingSamplesStart.Value, TrainingSamplesEnd.Value - TrainingSamplesStart.Value)
+                         .Where(i => i >= 0 && i < Dataset.Rows && (i < TestSamplesStart.Value || TestSamplesEnd.Value <= i));
+      }
+    }
+    public IEnumerable<int> TestIndizes {
+      get {
+        return Enumerable.Range(TestSamplesStart.Value, TestSamplesEnd.Value - TestSamplesStart.Value)
+           .Where(i => i >= 0 && i < Dataset.Rows);
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisProblemData(DataAnalysisProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEventHandlers();
+      RegisterParameterValueEventHandlers();
+    }
     public DataAnalysisProblemData()
       : base() {
@@ -181,4 +213,7 @@
       Parameters.Add(new ValueParameter<IntValue>("TestSamplesStart", new IntValue(15)));
       Parameters.Add(new ValueParameter<IntValue>("TestSamplesEnd", new IntValue(25)));
+      Parameters.Add(new ValueParameter<PercentValue>("ValidationPercentage", "The relative amount of the training samples that should be used as validation set.", new PercentValue(0.5)));
+
+      DatasetParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterParameterEventHandlers();
       RegisterParameterValueEventHandlers();
@@ -187,5 +222,5 @@
     public DataAnalysisProblemData(Dataset dataset, IEnumerable<string> inputVariables, string targetVariable,
       int trainingSamplesStart, int trainingSamplesEnd, int testSamplesStart, int testSamplesEnd) {
-      var inputVariablesList = new CheckedItemList<StringValue>(inputVariables.Select(x => new StringValue(x)));
+      var inputVariablesList = new CheckedItemList<StringValue>(inputVariables.Select(x => new StringValue(x)).ToList());
       StringValue targetVariableValue = new StringValue(targetVariable);
       var validTargetVariables = new ItemSet<StringValue>();
@@ -201,13 +236,21 @@
       Parameters.Add(new ValueParameter<IntValue>("TestSamplesStart", new IntValue(testSamplesStart)));
       Parameters.Add(new ValueParameter<IntValue>("TestSamplesEnd", new IntValue(testSamplesEnd)));
+      Parameters.Add(new ValueParameter<PercentValue>("ValidationPercentage", "The relative amount of the training samples that should be used as validation set.", new PercentValue(0.5)));
+
+      DatasetParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterParameterEventHandlers();
       RegisterParameterValueEventHandlers();
     }
 
-    [StorableConstructor]
-    private DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DataAnalysisProblemData(this, cloner);
+    }
 
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserializationHook() {
+    private void AfterDeserialization() {
+      if (!Parameters.ContainsKey("ValidationPercentage"))
+        Parameters.Add(new ValueParameter<PercentValue>("ValidationPercentage", "The relative amount of the training samples that should be used as validation set.", new PercentValue(0.5)));
+
+      DatasetParameter.ReactOnValueToStringChangedAndValueItemImageChanged = false;
       RegisterParameterEventHandlers();
       RegisterParameterValueEventHandlers();
@@ -217,5 +260,14 @@
     public event EventHandler ProblemDataChanged;
     protected virtual void OnProblemDataChanged(EventArgs e) {
-      if (!suppressEvents) {
+      if (TrainingSamplesStart.Value < 0) TrainingSamplesStart.Value = 0;
+      else if (TestSamplesStart.Value < 0) TestSamplesStart.Value = 0;
+      else if (TrainingSamplesEnd.Value > Dataset.Rows - 1) TrainingSamplesEnd.Value = Dataset.Rows - 1;
+      else if (TestSamplesEnd.Value > Dataset.Rows - 1) TestSamplesEnd.Value = Dataset.Rows - 1;
+      else if (TrainingSamplesStart.Value > TrainingSamplesEnd.Value) TrainingSamplesStart.Value = TestSamplesEnd.Value;
+      else if (TestSamplesStart.Value > TestSamplesEnd.Value) TestSamplesStart.Value = TestSamplesEnd.Value;
+      else if (ValidationPercentage.Value < 0) ValidationPercentage.Value = 0;
+      else if (ValidationPercentage.Value > 1) ValidationPercentage.Value = 1;
+      else if (!TrainingIndizes.Any()) throw new ArgumentException("No training samples are available.");
+      else if (!suppressEvents) {
         var listeners = ProblemDataChanged;
         if (listeners != null) listeners(this, e);
@@ -231,4 +283,5 @@
       TestSamplesStartParameter.ValueChanged += new EventHandler(TestSamplesStartParameter_ValueChanged);
       TestSamplesEndParameter.ValueChanged += new EventHandler(TestSamplesEndParameter_ValueChanged);
+      ValidationPercentageParameter.ValueChanged += new EventHandler(ValidationPercentageParameter_ValueChanged);
     }
 
@@ -240,4 +293,5 @@
       RegisterValueTypeEventHandlers(TestSamplesStart);
       RegisterValueTypeEventHandlers(TestSamplesEnd);
+      RegisterValueTypeEventHandlers(ValidationPercentage);
     }
 
@@ -271,4 +325,8 @@
     private void TestSamplesEndParameter_ValueChanged(object sender, EventArgs e) {
       RegisterValueTypeEventHandlers(TestSamplesEnd);
+      OnProblemDataChanged(EventArgs.Empty);
+    }
+    private void ValidationPercentageParameter_ValueChanged(object sender, EventArgs e) {
+      RegisterValueTypeEventHandlers(ValidationPercentage);
       OnProblemDataChanged(EventArgs.Empty);
     }
@@ -338,5 +396,5 @@
 
     public virtual void ImportFromFile(string fileName) {
-      var csvFileParser = new CsvFileParser();
+      var csvFileParser = new TableFileParser();
       csvFileParser.Parse(fileName);
       suppressEvents = true;
@@ -352,17 +410,10 @@
       InputVariables.SetItemCheckedState(variableNames.First(), false);
       int middle = (int)(csvFileParser.Rows * 0.5);
+      TrainingSamplesEnd = new IntValue(middle);
       TrainingSamplesStart = new IntValue(0);
-      TrainingSamplesEnd = new IntValue(middle);
+      TestSamplesEnd = new IntValue(csvFileParser.Rows);
       TestSamplesStart = new IntValue(middle);
-      TestSamplesEnd = new IntValue(csvFileParser.Rows);
       suppressEvents = false;
       OnProblemDataChanged(EventArgs.Empty);
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      DataAnalysisProblemData clone = (DataAnalysisProblemData)base.Clone(cloner);
-      clone.RegisterParameterEventHandlers();
-      clone.RegisterParameterValueEventHandlers();
-      return clone;
     }
   }
