Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/CsvFileParser.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/CsvFileParser.cs	(revision 5265)
+++ 	(revision )
@@ -1,316 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-
-namespace HeuristicLab.Problems.DataAnalysis {
-  public class CsvFileParser {
-    private const string VARIABLENAMES = "VARIABLENAMES";
-    private Tokenizer tokenizer;
-    private List<string> variableNames;
-    private List<List<double>> rowValues;
-
-    private int rows;
-    public int Rows {
-      get { return rows; }
-      set { rows = value; }
-    }
-
-    private int columns;
-    public int Columns {
-      get { return columns; }
-      set { columns = value; }
-    }
-
-    private double[,] values;
-    public double[,] Values {
-      get {
-        return values;
-      }
-    }
-
-    public IEnumerable<string> VariableNames {
-      get {
-        if (variableNames.Count > 0) return variableNames;
-        else {
-          string[] names = new string[columns];
-          for (int i = 0; i < names.Length; i++) {
-            names[i] = "X" + i.ToString("000");
-          }
-          return names;
-        }
-      }
-    }
-
-    public CsvFileParser() {
-      rowValues = new List<List<double>>();
-      variableNames = new List<string>();
-    }
-
-    private void Reset() {
-      variableNames.Clear();
-      rowValues.Clear();
-    }
-
-    public void Parse(string fileName) {
-      TryParse(fileName);
-      // translate the list of samples into a DoubleMatrixData item
-      rows = rowValues.Count;
-      columns = rowValues[0].Count;
-      values = new double[rows, columns];
-
-      int rowIndex = 0;
-      int columnIndex = 0;
-      foreach (List<double> row in rowValues) {
-        columnIndex = 0;
-        foreach (double element in row) {
-          values[rowIndex, columnIndex++] = element;
-        }
-        rowIndex++;
-      }
-    }
-
-    private void TryParse(string fileName) {
-      Exception lastEx = null;
-      NumberFormatInfo[] possibleFormats = new NumberFormatInfo[] { CultureInfo.InvariantCulture.NumberFormat };
-      foreach (NumberFormatInfo numberFormat in possibleFormats) {
-        using (StreamReader reader = new StreamReader(fileName)) {
-          tokenizer = new Tokenizer(reader, numberFormat);
-          try {
-            // parse the file
-            Parse();
-            return; // parsed without errors -> return;
-          }
-          catch (DataFormatException ex) {
-            lastEx = ex;
-          }
-        }
-      }
-      // all number formats threw an exception -> rethrow the last exception
-      throw lastEx;
-    }
-
-    #region tokenizer
-    internal enum TokenTypeEnum {
-      NewLine, Separator, String, Double
-    }
-
-    internal class Token {
-      public TokenTypeEnum type;
-      public string stringValue;
-      public double doubleValue;
-
-      public Token(TokenTypeEnum type, string value) {
-        this.type = type;
-        stringValue = value;
-        doubleValue = 0.0;
-      }
-
-      public override string ToString() {
-        return stringValue;
-      }
-    }
-
-
-    internal class Tokenizer {
-      private StreamReader reader;
-      private List<Token> tokens;
-      private NumberFormatInfo numberFormatInfo;
-
-      private int currentLineNumber = 0;
-      public int CurrentLineNumber {
-        get { return currentLineNumber; }
-        private set { currentLineNumber = value; }
-      }
-      private string currentLine;
-      public string CurrentLine {
-        get { return currentLine; }
-        private set { currentLine = value; }
-      }
-
-      private Token newlineToken;
-      public Token NewlineToken {
-        get { return newlineToken; }
-        private set { newlineToken = value; }
-      }
-      private Token separatorToken;
-      public Token SeparatorToken {
-        get { return separatorToken; }
-        private set { separatorToken = value; }
-      }
-
-      public Tokenizer(StreamReader reader, NumberFormatInfo numberFormatInfo, char separator) {
-        this.reader = reader;
-        this.numberFormatInfo = numberFormatInfo;
-        separatorToken = new Token(TokenTypeEnum.Separator, separator.ToString());
-        newlineToken = new Token(TokenTypeEnum.NewLine, Environment.NewLine);
-        tokens = new List<Token>();
-        ReadNextTokens();
-      }
-      public Tokenizer(StreamReader reader, NumberFormatInfo numberFormatInfo)
-        : this(reader, numberFormatInfo, ';') {
-      }
-
-      private void ReadNextTokens() {
-        if (!reader.EndOfStream) {
-          CurrentLine = reader.ReadLine();
-          var newTokens = from str in Split(CurrentLine)
-                          let trimmedStr = str.Trim()
-                          where !string.IsNullOrEmpty(trimmedStr)
-                          select MakeToken(trimmedStr.Trim());
-
-          tokens.AddRange(newTokens);
-          tokens.Add(NewlineToken);
-          CurrentLineNumber++;
-        }
-      }
-
-      private IEnumerable<string> Split(string line) {
-        StringBuilder subStr = new StringBuilder();
-        foreach (char c in line) {
-          if (c == ';') {
-            yield return subStr.ToString();
-            subStr = new StringBuilder();
-            yield return c.ToString();
-          } else {
-            subStr.Append(c);
-          }
-        }
-        yield return subStr.ToString();
-      }
-
-      private Token MakeToken(string strToken) {
-        Token token = new Token(TokenTypeEnum.String, strToken);
-        if (strToken.Equals(SeparatorToken.stringValue)) {
-          return SeparatorToken;
-        } else if (double.TryParse(strToken, NumberStyles.Float, numberFormatInfo, out token.doubleValue)) {
-          token.type = TokenTypeEnum.Double;
-          return token;
-        }
-
-        // couldn't parse the token as an int or float number so return a string token
-        return token;
-      }
-
-      public Token Peek() {
-        return tokens[0];
-      }
-
-      public Token Next() {
-        Token next = tokens[0];
-        tokens.RemoveAt(0);
-        if (tokens.Count == 0) {
-          ReadNextTokens();
-        }
-        return next;
-      }
-
-      public bool HasNext() {
-        return tokens.Count > 0 || !reader.EndOfStream;
-      }
-    }
-    #endregion
-
-    #region parsing
-    private void Parse() {
-      ParseVariableNames();
-      if (!tokenizer.HasNext()) Error("Couldn't parse data values. Probably because of incorrect number format (the parser expects english number format with a '.' as decimal separator).", "", tokenizer.CurrentLineNumber);
-      ParseValues();
-      if (rowValues.Count == 0) Error("Couldn't parse data values. Probably because of incorrect number format (the parser expects english number format with a '.' as decimal separator).", "", tokenizer.CurrentLineNumber);
-    }
-
-    private void ParseValues() {
-      while (tokenizer.HasNext()) {
-        List<double> row = new List<double>();
-        row.Add(NextValue(tokenizer));
-        while (tokenizer.HasNext() && tokenizer.Peek() == tokenizer.SeparatorToken) {
-          Expect(tokenizer.SeparatorToken);
-          row.Add(NextValue(tokenizer));
-        }
-        Expect(tokenizer.NewlineToken);
-        // all rows have to have the same number of values            
-        // the first row defines how many samples are needed
-        if (rowValues.Count > 0 && rowValues[0].Count != row.Count) {
-          Error("The first row of the dataset has " + rowValues[0].Count + " columns." +
-            "\nLine " + tokenizer.CurrentLineNumber + " has " + row.Count + " columns.", "", tokenizer.CurrentLineNumber);
-        }
-        // add the current row to the collection of rows and start a new row
-        rowValues.Add(row);
-        row = new List<double>();
-      }
-    }
-
-    private double NextValue(Tokenizer tokenizer) {
-      if (tokenizer.Peek() == tokenizer.SeparatorToken || tokenizer.Peek() == tokenizer.NewlineToken) return double.NaN;
-      Token current = tokenizer.Next();
-      if (current.type == TokenTypeEnum.Separator || current.type == TokenTypeEnum.String) {
-        return double.NaN;
-      } else if (current.type == TokenTypeEnum.Double) {
-        // just take the value
-        return current.doubleValue;
-      }
-      // found an unexpected token => throw error 
-      Error("Unexpected token.", current.stringValue, tokenizer.CurrentLineNumber);
-      // this line is never executed because Error() throws an exception
-      throw new InvalidOperationException();
-    }
-
-    private void ParseVariableNames() {
-      // if the first line doesn't start with a double value then we assume that the
-      // first line contains variable names
-      if (tokenizer.HasNext() && tokenizer.Peek().type != TokenTypeEnum.Double) {
-
-        List<Token> tokens = new List<Token>();
-        Token valueToken;
-        valueToken = tokenizer.Next();
-        tokens.Add(valueToken);
-        while (tokenizer.HasNext() && tokenizer.Peek() == tokenizer.SeparatorToken) {
-          Expect(tokenizer.SeparatorToken);
-          valueToken = tokenizer.Next();
-          if (valueToken != tokenizer.NewlineToken) {
-            tokens.Add(valueToken);
-          }
-        }
-        if (valueToken != tokenizer.NewlineToken) {
-          Expect(tokenizer.NewlineToken);
-        }
-        variableNames = tokens.Select(x => x.stringValue.Trim()).ToList();
-      }
-    }
-
-    private void Expect(Token expectedToken) {
-      Token actualToken = tokenizer.Next();
-      if (actualToken != expectedToken) {
-        Error("Expected: " + expectedToken, actualToken.stringValue, tokenizer.CurrentLineNumber);
-      }
-    }
-
-    private void Error(string message, string token, int lineNumber) {
-      throw new DataFormatException("Error while parsing.\n" + message, token, lineNumber);
-    }
-    #endregion
-  }
-}
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblem.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblem.cs	(revision 5275)
@@ -35,9 +35,10 @@
   public class DataAnalysisProblem : ParameterizedNamedItem, IDataAnalysisProblem, IStorableContent {
     private const string DataAnalysisProblemDataParameterName = "DataAnalysisProblemData";
+
+    public string Filename { get; set; }
+
     public override Image ItemImage {
       get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Type; }
     }
-
-    public string Filename { get; set; }
 
     #region Parameter Properties
@@ -54,4 +55,10 @@
     [StorableConstructor]
     protected DataAnalysisProblem(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisProblem(DataAnalysisProblem original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+      RegisterParameterValueEvents();
+    }
+
     public DataAnalysisProblem()
       : base() {
@@ -62,5 +69,5 @@
 
     [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserializationHook() {
+    private void AfterDeserialization() {
       RegisterParameterEvents();
       RegisterParameterValueEvents();
@@ -90,8 +97,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      DataAnalysisProblem clone = (DataAnalysisProblem)base.Clone(cloner);
-      clone.RegisterParameterEvents();
-      clone.RegisterParameterValueEvents();
-      return clone;
+      return new DataAnalysisProblem(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblemData.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisProblemData.cs	(revision 5265)
+++ 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;
     }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 5275)
@@ -38,5 +38,14 @@
     #endregion
 
-
+    [StorableConstructor]
+    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
+      : base(original, cloner) {
+      problemData = (DataAnalysisProblemData)cloner.Clone(original.problemData);
+      model = (IDataAnalysisModel)cloner.Clone(original.model);
+      lowerEstimationLimit = original.lowerEstimationLimit;
+      upperEstimationLimit = original.upperEstimationLimit;
+      AfterDeserialization();
+    }
     protected DataAnalysisSolution()
       : base() { }
@@ -47,11 +56,9 @@
       this.lowerEstimationLimit = lowerEstimationLimit;
       this.upperEstimationLimit = upperEstimationLimit;
-      Initialize();
+      AfterDeserialization();
     }
 
-    [StorableConstructor]
-    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
     [StorableHook(HookType.AfterDeserialization)]
-    private void Initialize() {
+    private void AfterDeserialization() {
       if (problemData != null)
         RegisterProblemDataEvents();
@@ -134,5 +141,4 @@
     public event EventHandler ProblemDataChanged;
     protected virtual void OnProblemDataChanged() {
-      RecalculateEstimatedValues();
       var listeners = ProblemDataChanged;
       if (listeners != null)
@@ -142,7 +148,7 @@
     public event EventHandler ModelChanged;
     protected virtual void OnModelChanged() {
-      EventHandler handler = ModelChanged;
-      if (handler != null)
-        handler(this, EventArgs.Empty);
+      EventHandler listeners = ModelChanged;
+      if (listeners != null)
+        listeners(this, EventArgs.Empty);
     }
 
@@ -155,14 +161,4 @@
     #endregion
 
-    public override IDeepCloneable Clone(Cloner cloner) {
-      DataAnalysisSolution clone = (DataAnalysisSolution)base.Clone(cloner);
-      clone.problemData = (DataAnalysisProblemData)cloner.Clone(problemData);
-      clone.model = (IDataAnalysisModel)cloner.Clone(model);
-      clone.lowerEstimationLimit = lowerEstimationLimit;
-      clone.upperEstimationLimit = upperEstimationLimit;
-      clone.Initialize();
-
-      return clone;
-    }
   }
 }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataFormatException.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataFormatException.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/DataFormatException.cs	(revision 5275)
@@ -21,6 +21,8 @@
 
 using System;
+using System.Runtime.Serialization;
 
 namespace HeuristicLab.Problems.DataAnalysis {
+  [Serializable]
   public class DataFormatException : Exception {
     private int line;
@@ -37,4 +39,6 @@
       this.line = line;
     }
+
+    public DataFormatException(SerializationInfo info, StreamingContext context) : base(info, context) { }
   }
 }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Dataset.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Dataset.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Dataset.cs	(revision 5275)
@@ -32,14 +32,11 @@
   [StorableClass]
   public sealed class Dataset : NamedItem, IStringConvertibleMatrix {
-    // empty constructor for cloning
-    private Dataset()
-      : base() {
-    }
-
     [StorableConstructor]
-    private Dataset(bool deserializing)
-      : base(deserializing) {
-    }
-
+    private Dataset(bool deserializing) : base(deserializing) { }
+    private Dataset(Dataset original, Cloner cloner)
+      : base(original, cloner) {
+      variableNames = original.variableNames;
+      data = original.data;
+    }
     public Dataset(IEnumerable<string> variableNames, double[,] data)
       : base() {
@@ -122,6 +119,4 @@
     }
 
-
-
     public string GetVariableName(int variableIndex) {
       return variableNames[variableIndex];
@@ -140,8 +135,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      Dataset clone = (Dataset)base.Clone(cloner);
-      clone.variableNames = variableNames;
-      clone.data = data;
-      return clone;
+      return new Dataset(this, cloner);
     }
 
@@ -195,26 +187,37 @@
     }
 
+    public event EventHandler ColumnsChanged;
+    private void OnColumnsChanged() {
+      var handler = ColumnsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    public event EventHandler RowsChanged;
+    private void OnRowsChanged() {
+      var handler = RowsChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
     public event EventHandler ColumnNamesChanged;
     private void OnColumnNamesChanged() {
-      EventHandler handler = ColumnNamesChanged;
-      if (handler != null)
-        handler(this, EventArgs.Empty);
+      EventHandler listeners = ColumnNamesChanged;
+      if (listeners != null)
+        listeners(this, EventArgs.Empty);
     }
     public event EventHandler RowNamesChanged;
     private void OnRowNamesChanged() {
-      EventHandler handler = RowNamesChanged;
-      if (handler != null)
-        handler(this, EventArgs.Empty);
+      EventHandler listeners = RowNamesChanged;
+      if (listeners != null)
+        listeners(this, EventArgs.Empty);
     }
     public event EventHandler SortableViewChanged;
     private void OnSortableViewChanged() {
-      EventHandler handler = SortableViewChanged;
-      if (handler != null)
-        handler(this, EventArgs.Empty);
+      EventHandler listeners = SortableViewChanged;
+      if (listeners != null)
+        listeners(this, EventArgs.Empty);
     }
     public event EventHandler<EventArgs<int, int>> ItemChanged;
     private void OnItemChanged(int rowIndex, int columnIndex) {
-      if (ItemChanged != null)
-        ItemChanged(this, new EventArgs<int, int>(rowIndex, columnIndex));
+      var listeners = ItemChanged;
+      if (listeners != null)
+        listeners(this, new EventArgs<int, int>(rowIndex, columnIndex));
       OnToStringChanged();
     }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/OnlineCovarianceEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/OnlineCovarianceEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/OnlineCovarianceEvaluator.cs	(revision 5275)
@@ -25,5 +25,5 @@
   public class OnlineCovarianceEvaluator : IOnlineEvaluator {
 
-    private double xMean, yMean, Cn;
+    private double originalMean, estimatedMean, Cn;
     private int n;
     public double Covariance {
@@ -47,22 +47,21 @@
       n = 0;
       Cn = 0.0;
-      xMean = 0.0;
-      yMean = 0.0;
+      originalMean = 0.0;
+      estimatedMean = 0.0;
     }
 
-    public void Add(double x, double y) {
-      if (double.IsNaN(x) || double.IsInfinity(x) ||
-          double.IsNaN(y) || double.IsInfinity(y)) {
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original)) {
         throw new ArgumentException("Covariance is not defined for series containing NaN or infinity elements");
       } else {
         n++;
         // online calculation of tMean
-
-        xMean = xMean + (x - xMean) / n;
-        double deltaY = y - yMean; // delta = (y - yMean(n-1))
-        yMean = yMean + deltaY / n;
+        originalMean = originalMean + (original - originalMean) / n;
+        double delta = estimated - estimatedMean; // delta = (y - yMean(n-1))
+        estimatedMean = estimatedMean + delta / n;
 
         // online calculation of covariance
-        Cn = Cn + deltaY * (x - xMean); // C(n) = C(n-1) + (y - yMean(n-1)) (x - xMean(n))
+        Cn = Cn + delta * (original - originalMean); // C(n) = C(n-1) + (y - yMean(n-1)) (t - tMean(n))       
       }
     }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleEvaluator.cs	(revision 5275)
@@ -20,8 +20,10 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
 using HeuristicLab.Operators;
 using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
@@ -32,4 +34,9 @@
     public ILookupParameter<DoubleMatrix> ValuesParameter {
       get { return (ILookupParameter<DoubleMatrix>)Parameters["Values"]; }
+    }
+    [StorableConstructor]
+    protected SimpleEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleEvaluator(SimpleEvaluator original, Cloner cloner)
+      : base(original, cloner) {
     }
     public SimpleEvaluator()
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMSEEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMSEEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMSEEvaluator.cs	(revision 5275)
@@ -23,7 +23,9 @@
 using System.Collections.Generic;
 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.Evaluators {
@@ -34,4 +36,12 @@
     }
 
+    [StorableConstructor]
+    protected SimpleMSEEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleMSEEvaluator(SimpleMSEEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleMSEEvaluator(this, cloner);
+    }
     public SimpleMSEEvaluator() {
       Parameters.Add(new LookupParameter<DoubleValue>("MeanSquaredError", "The mean squared error of estimated values."));
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageErrorEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageErrorEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageErrorEvaluator.cs	(revision 5275)
@@ -23,7 +23,9 @@
 using System.Collections.Generic;
 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.Evaluators {
@@ -33,4 +35,9 @@
     }
 
+    [StorableConstructor]
+    protected SimpleMeanAbsolutePercentageErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleMeanAbsolutePercentageErrorEvaluator(SimpleMeanAbsolutePercentageErrorEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public SimpleMeanAbsolutePercentageErrorEvaluator() {
       Parameters.Add(new LookupParameter<PercentValue>("AverageRelativeError", "The average relative error of estimated values."));
@@ -43,4 +50,8 @@
                       select values[i, ESTIMATION_INDEX];
       AverageRelativeErrorParameter.ActualValue = new PercentValue(Calculate(original, estimated));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleMeanAbsolutePercentageErrorEvaluator(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleMeanAbsolutePercentageOfRangeErrorEvaluator.cs	(revision 5275)
@@ -27,4 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
@@ -35,4 +36,9 @@
     }
 
+    [StorableConstructor]
+    protected SimpleMeanAbsolutePercentageOfRangeErrorEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleMeanAbsolutePercentageOfRangeErrorEvaluator(SimpleMeanAbsolutePercentageOfRangeErrorEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public SimpleMeanAbsolutePercentageOfRangeErrorEvaluator() {
       Parameters.Add(new LookupParameter<PercentValue>("AveragePercentageOfRangeError", "The average relative (percentage of range) error of estimated values."));
@@ -45,4 +51,8 @@
                       select values[i, ESTIMATION_INDEX];
       AveragePercentageOfRangeErrorParameter.ActualValue = new PercentValue(Calculate(original, estimated));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleMeanAbsolutePercentageOfRangeErrorEvaluator(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleNMSEEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleNMSEEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleNMSEEvaluator.cs	(revision 5275)
@@ -23,7 +23,9 @@
 using System.Collections.Generic;
 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.Evaluators {
@@ -34,4 +36,12 @@
     }
 
+    [StorableConstructor]
+    protected SimpleNMSEEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleNMSEEvaluator(SimpleNMSEEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleNMSEEvaluator(this, cloner);
+    }
     public SimpleNMSEEvaluator() {
       Parameters.Add(new LookupParameter<DoubleValue>("NormalizedMeanSquaredError", "The normalized mean squared error (divided by variance) of estimated values."));
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleRSquaredEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleRSquaredEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleRSquaredEvaluator.cs	(revision 5275)
@@ -23,7 +23,9 @@
 using System.Collections.Generic;
 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.Evaluators {
@@ -32,5 +34,12 @@
       get { return (ILookupParameter<DoubleValue>)Parameters["RSquared"]; }
     }
-
+    [StorableConstructor]
+    protected SimpleRSquaredEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleRSquaredEvaluator(SimpleRSquaredEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleRSquaredEvaluator(this, cloner);
+    }
     public SimpleRSquaredEvaluator() {
       Parameters.Add(new LookupParameter<DoubleValue>("RSquared", "The squared Pearson's Product Moment Correlation (R²) of estimated values and original values."));
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleVarianceAccountedForEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleVarianceAccountedForEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Evaluators/SimpleVarianceAccountedForEvaluator.cs	(revision 5275)
@@ -27,4 +27,5 @@
 using HeuristicLab.Data;
 using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis.Evaluators {
@@ -40,4 +41,12 @@
     }
 
+    [StorableConstructor]
+    protected SimpleVarianceAccountedForEvaluator(bool deserializing) : base(deserializing) { }
+    protected SimpleVarianceAccountedForEvaluator(SimpleVarianceAccountedForEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleVarianceAccountedForEvaluator(this, cloner);
+    }
     public SimpleVarianceAccountedForEvaluator() {
       Parameters.Add(new LookupParameter<DoubleValue>("VarianceAccountedFor", "The variance of the original values accounted for by the estimated values (VAF(y,y') = 1 - var(y-y') / var(y) )."));
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 5275)
@@ -107,4 +107,7 @@
       <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
     </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Core-3.3">
       <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
@@ -158,4 +161,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Interfaces\ISingleObjectiveDataAnalysisProblem.cs" />
+    <Compile Include="TableFileParser.cs" />
     <None Include="HeuristicLab.snk" />
     <None Include="HeuristicLabProblemsDataAnalysisPlugin.cs.frame" />
@@ -166,5 +171,4 @@
     <Compile Include="Evaluators\OnlineNormalizedMeanSquaredErrorEvaluator.cs" />
     <Compile Include="DataAnalysisSolution.cs" />
-    <Compile Include="CsvFileParser.cs" />
     <Compile Include="DataAnalysisProblem.cs" />
     <Compile Include="DataAnalysisProblemData.cs" />
@@ -269,3 +273,7 @@
 SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisPlugin.cs"</PreBuildEvent>
   </PropertyGroup>
+  <PropertyGroup>
+    <PostBuildEvent>
+    </PostBuildEvent>
+  </PropertyGroup>
 </Project>
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLabProblemsDataAnalysisPlugin.cs.frame
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLabProblemsDataAnalysisPlugin.cs.frame	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLabProblemsDataAnalysisPlugin.cs.frame	(revision 5275)
@@ -28,5 +28,5 @@
   [Plugin("HeuristicLab.Problems.DataAnalysis","3.3.0.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis-3.3.dll", PluginFileType.Assembly)]
-  [PluginDependency("HeuristicLab.ALGLIB", "2.5")]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.1")]
   [PluginDependency("HeuristicLab.Collections", "3.3.0.0")]
   [PluginDependency("HeuristicLab.Common", "3.3.0.0")]
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IDataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IDataAnalysisProblem.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IDataAnalysisProblem.cs	(revision 5275)
@@ -24,4 +24,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface IDataAnalysisProblem : IProblem {
+    DataAnalysisProblemData DataAnalysisProblemData { get; }
   }
 }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/ISingleObjectiveDataAnalysisProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/ISingleObjectiveDataAnalysisProblem.cs	(revision 5275)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/ISingleObjectiveDataAnalysisProblem.cs	(revision 5275)
@@ -0,0 +1,26 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Optimization;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ISingleObjectiveDataAnalysisProblem : ISingleObjectiveProblem, IDataAnalysisProblem {
+  }
+}
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressure.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressure.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressure.cs	(revision 5275)
@@ -32,4 +32,5 @@
 using HeuristicLab.Problems.DataAnalysis.Evaluators;
 using HeuristicLab.Analysis;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -80,5 +81,6 @@
     }
 
-    public CovariantParsimonyPressure(bool deserializing) : base(deserializing) { }
+    protected CovariantParsimonyPressure(bool deserializing) : base(deserializing) { }
+    protected CovariantParsimonyPressure(CovariantParsimonyPressure original, Cloner clone) : base(original, clone) { }
     public CovariantParsimonyPressure()
       : base() {
@@ -98,4 +100,9 @@
       Parameters.Add(new ValueLookupParameter<BoolValue>("InvertComplexityAdaption"));
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovariantParsimonyPressure(this, cloner);
+    }
+
 
     [StorableHook(Persistence.Default.CompositeSerializers.Storable.HookType.AfterDeserialization)]
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressureAdder.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressureAdder.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/CovariantParsimonyPressureAdder.cs	(revision 5275)
@@ -32,4 +32,5 @@
 using HeuristicLab.Problems.DataAnalysis.Evaluators;
 using HeuristicLab.Analysis;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -66,5 +67,6 @@
 
     [StorableConstructor]
-    public CovariantParsimonyPressureAdder(bool deserializing) : base(deserializing) { }
+    protected CovariantParsimonyPressureAdder(bool deserializing) : base(deserializing) { }
+    protected CovariantParsimonyPressureAdder(CovariantParsimonyPressureAdder original, Cloner cloner) : base(original, cloner) { }
     public CovariantParsimonyPressureAdder()
       : base() {
@@ -79,5 +81,7 @@
       Parameters.Add(new ValueLookupParameter<BoolValue>("ApplyParsimonyPressure"));
     }
-
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new CovariantParsimonyPressureAdder(this, cloner);
+    }
     [StorableHook(Persistence.Default.CompositeSerializers.Storable.HookType.AfterDeserialization)]
     private void AfterDeserialization() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqComparator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqComparator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqComparator.cs	(revision 5275)
@@ -30,4 +30,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -81,4 +82,9 @@
     }
 
+    [StorableConstructor]
+    protected DynOpEqComparator(bool deserializing) : base(deserializing) { }
+    protected DynOpEqComparator(DynOpEqComparator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public DynOpEqComparator()
       : base() {
@@ -100,4 +106,7 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynOpEqComparator(this, cloner);
+    }
     public override IOperation Apply() {
       if (ResultParameter.ActualValue == null || ResultParameter.ActualValue.Value == true) {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqHistogramInitializer.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqHistogramInitializer.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynOpEqHistogramInitializer.cs	(revision 5275)
@@ -30,4 +30,5 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -63,4 +64,9 @@
     }
 
+    [StorableConstructor]
+    protected DynOpEqHistogramInitializer(bool deserializing) : base(deserializing) { }
+    protected DynOpEqHistogramInitializer(DynOpEqHistogramInitializer original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public DynOpEqHistogramInitializer()
       : base() {
@@ -75,5 +81,7 @@
       Parameters.Add(new LookupParameter<BoolValue>("Maximization"));
     }
-
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynOpEqHistogramInitializer(this, cloner);
+    }
     public override IOperation Apply() {
       if (BinCapacityParameter.ActualValue == null) {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitComparator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitComparator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitComparator.cs	(revision 5275)
@@ -29,4 +29,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -65,4 +66,10 @@
     }
 
+    [StorableConstructor]
+    protected DynamicDepthLimitComparator(bool deserializing) : base(deserializing) { }
+    protected DynamicDepthLimitComparator(DynamicDepthLimitComparator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
     public DynamicDepthLimitComparator()
       : base() {
@@ -77,4 +84,8 @@
       Parameters.Add(new ValueParameter<DoubleValue>("cLower", "", new DoubleValue(0.03)));
       Parameters.Add(new ValueParameter<DoubleValue>("cRaise", "", new DoubleValue(0.015)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynamicDepthLimitComparator(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitInitializer.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitInitializer.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/DynamicDepthLimitInitializer.cs	(revision 5275)
@@ -29,4 +29,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -41,8 +42,16 @@
     }
 
+    [StorableConstructor]
+    protected DynamicDepthLimitInitializer(bool deserializing) : base(deserializing) { }
+    protected DynamicDepthLimitInitializer(DynamicDepthLimitInitializer original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public DynamicDepthLimitInitializer()
       : base() {
       Parameters.Add(new ValueLookupParameter<IntValue>("DynamicDepthLimit", "The current depth limit."));
       Parameters.Add(new ValueLookupParameter<IntValue>("InitialDepthLimit", "The initial depth limit."));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DynamicDepthLimitInitializer(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/WeightedParentsQualityVarianceComparator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/WeightedParentsQualityVarianceComparator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Operators/WeightedParentsQualityVarianceComparator.cs	(revision 5275)
@@ -28,4 +28,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.Operators {
@@ -61,4 +62,9 @@
     }
 
+    [StorableConstructor]
+    protected WeightedParentsQualityVarianceComparator(bool deserializing) : base(deserializing) { }
+    protected WeightedParentsQualityVarianceComparator(WeightedParentsQualityVarianceComparator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public WeightedParentsQualityVarianceComparator()
       : base() {
@@ -75,5 +81,7 @@
       Parameters.Add(new ScopeTreeLookupParameter<IntValue>("RightSideSamples", "The number of samples used to calculate the quality of the parent."));
     }
-
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new WeightedParentsQualityVarianceComparator(this, cloner);
+    }
     public override IOperation Apply() {
       double leftQuality = LeftSideParameter.ActualValue.Value;
@@ -114,9 +122,9 @@
       double stat = (xmean - ymean) / Math.Sqrt(xvar / n + yvar / m);
       double c = xvar / n / (xvar / n + yvar / m);
-      double df = (n - 1) * (m - 1) / ((m - 1) * AP.Math.Sqr(c) + (n - 1) * (1 - AP.Math.Sqr(c)));
+      double df = (n - 1) * (m - 1) / ((m - 1) * alglib.math.sqr(c) + (n - 1) * (1 - alglib.math.sqr(c)));
       if ((double)(stat) > (double)(0))
-        p = 1 - 0.5 * ibetaf.incompletebeta(df / 2, 0.5, df / (df + AP.Math.Sqr(stat)));
+        p = 1 - 0.5 * alglib.ibetaf.incompletebeta(df / 2, 0.5, df / (df + alglib.math.sqr(stat)));
       else
-        p = 0.5 * ibetaf.incompletebeta(df / 2, 0.5, df / (df + AP.Math.Sqr(stat)));
+        p = 0.5 * alglib.ibetaf.incompletebeta(df / 2, 0.5, df / (df + alglib.math.sqr(stat)));
       double bothtails = 2 * Math.Min(p, 1 - p);
       double lefttail = p;
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer.cs	(revision 5275)
@@ -30,4 +30,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis.Evaluators;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.SupportVectorMachine.ParameterAdjustmentProblem {
@@ -89,5 +90,9 @@
 
     #endregion
-
+    [StorableConstructor]
+    protected SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+    protected SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer(SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer()
       : base() {
@@ -103,5 +108,7 @@
       Parameters.Add(new LookupParameter<ResultCollection>(ResultsParameterName, "The result collection where the best support vector solution should be stored."));
     }
-
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SupportVectorMachineParameterAdjustmentBestSolutionAnalyzer(this, cloner);
+    }
     public override IOperation Apply() {
       var points = ParameterVectorParameter.ActualValue;
@@ -124,5 +131,5 @@
       if (bestModel == null) {
         bestModel = SupportVectorMachineModelCreator.TrainModel(DataAnalysisProblemData,
-          DataAnalysisProblemData.TrainingSamplesStart.Value, DataAnalysisProblemData.TrainingSamplesEnd.Value,
+          DataAnalysisProblemData.TrainingIndizes,
           SvmType.Value, KernelType.Value, cost, nu, gamma, 0.0);
         BestSolutionParameter.ActualValue = bestModel;
@@ -153,5 +160,5 @@
         if (BestSolutionQualityParameter.ActualValue.Value > bestQuality) {
           bestModel = SupportVectorMachineModelCreator.TrainModel(DataAnalysisProblemData,
-            DataAnalysisProblemData.TrainingSamplesStart.Value, DataAnalysisProblemData.TrainingSamplesEnd.Value,
+            DataAnalysisProblemData.TrainingIndizes,
             SvmType.Value, KernelType.Value, cost, nu, gamma, 0.0);
           BestSolutionParameter.ActualValue = bestModel;
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentEvaluator.cs	(revision 5275)
@@ -28,4 +28,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis.SupportVectorMachine.ParameterAdjustmentProblem {
@@ -107,5 +108,9 @@
     }
     #endregion
-
+    [StorableConstructor]
+    protected SupportVectorMachineParameterAdjustmentEvaluator(bool deserializing) : base(deserializing) { }
+    protected SupportVectorMachineParameterAdjustmentEvaluator(SupportVectorMachineParameterAdjustmentEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public SupportVectorMachineParameterAdjustmentEvaluator()
       : base() {
@@ -130,4 +135,7 @@
       evaluator.Successor = null;
     }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SupportVectorMachineParameterAdjustmentEvaluator(this, cloner);
+    }
 
     public override IOperation Apply() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentProblem.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentProblem.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/ParameterAdjustmentProblem/SupportVectorMachineParameterAdjustmentProblem.cs	(revision 5275)
@@ -130,4 +130,15 @@
     [StorableConstructor]
     private SupportVectorMachineParameterAdjustmentProblem(bool deserializing) : base(deserializing) { }
+    private SupportVectorMachineParameterAdjustmentProblem(SupportVectorMachineParameterAdjustmentProblem original, Cloner cloner)
+      : base(original, cloner) {
+      operators = original.operators.Where(x => IsNotFieldReferenced(x)).Select(x => (IOperator)cloner.Clone(x)).ToList();
+      strategyVectorCreator = (StdDevStrategyVectorCreator)cloner.Clone(original.strategyVectorCreator);
+      operators.Add(strategyVectorCreator);
+      strategyVectorCrossover = (StdDevStrategyVectorCrossover)cloner.Clone(original.strategyVectorCrossover);
+      operators.Add(strategyVectorCrossover);
+      strategyVectorManipulator = (StdDevStrategyVectorManipulator)cloner.Clone(original.strategyVectorManipulator);
+      operators.Add(strategyVectorManipulator);
+      AttachEventHandlers();
+    }
     public SupportVectorMachineParameterAdjustmentProblem()
       : base() {
@@ -167,16 +178,6 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      SupportVectorMachineParameterAdjustmentProblem clone = (SupportVectorMachineParameterAdjustmentProblem)base.Clone(cloner);
-      clone.operators = operators.Where(x => IsNotFieldReferenced(x)).Select(x => (IOperator)cloner.Clone(x)).ToList();
-      clone.strategyVectorCreator = (StdDevStrategyVectorCreator)cloner.Clone(strategyVectorCreator);
-      clone.operators.Add(clone.strategyVectorCreator);
-      clone.strategyVectorCrossover = (StdDevStrategyVectorCrossover)cloner.Clone(strategyVectorCrossover);
-      clone.operators.Add(strategyVectorCrossover);
-      clone.strategyVectorManipulator = (StdDevStrategyVectorManipulator)cloner.Clone(strategyVectorManipulator);
-      clone.operators.Add(strategyVectorManipulator);
-      clone.AttachEventHandlers();
-      return clone;
-    }
-
+      return new SupportVectorMachineParameterAdjustmentProblem(this, cloner);
+    }
     private bool IsNotFieldReferenced(IOperator x) {
       return !(x == strategyVectorCreator
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineCrossValidationEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineCrossValidationEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineCrossValidationEvaluator.cs	(revision 5275)
@@ -21,5 +21,7 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -125,4 +127,10 @@
     #endregion
 
+    [StorableConstructor]
+    protected SupportVectorMachineCrossValidationEvaluator(bool deserializing) : base(deserializing) { }
+
+    protected SupportVectorMachineCrossValidationEvaluator(SupportVectorMachineCrossValidationEvaluator original,
+      Cloner cloner)
+      : base(original, cloner) { }
     public SupportVectorMachineCrossValidationEvaluator()
       : base() {
@@ -142,15 +150,27 @@
     }
 
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SupportVectorMachineCrossValidationEvaluator(this, cloner);
+    }
+
     public override IOperation Apply() {
-      double reductionRatio = 1.0;
+      double reductionRatio = 1.0; // TODO: make parameter
       if (ActualSamplesParameter.ActualValue != null)
         reductionRatio = ActualSamplesParameter.ActualValue.Value;
-
-      int reducedRows = (int)((SamplesEnd.Value - SamplesStart.Value) * reductionRatio);
+      IEnumerable<int> rows =
+        Enumerable.Range(SamplesStart.Value, SamplesEnd.Value - SamplesStart.Value)
+        .Where(i => i < DataAnalysisProblemData.TestSamplesStart.Value || DataAnalysisProblemData.TestSamplesEnd.Value <= i);
+
+      // create a new DataAnalysisProblemData instance
       DataAnalysisProblemData reducedProblemData = (DataAnalysisProblemData)DataAnalysisProblemData.Clone();
-      reducedProblemData.Dataset = CreateReducedDataset(RandomParameter.ActualValue, reducedProblemData.Dataset, reductionRatio, SamplesStart.Value, SamplesEnd.Value);
+      reducedProblemData.Dataset =
+        CreateReducedDataset(RandomParameter.ActualValue, reducedProblemData.Dataset, rows, reductionRatio);
+      reducedProblemData.TrainingSamplesStart.Value = 0;
+      reducedProblemData.TrainingSamplesEnd.Value = reducedProblemData.Dataset.Rows;
+      reducedProblemData.TestSamplesStart.Value = reducedProblemData.Dataset.Rows;
+      reducedProblemData.TestSamplesEnd.Value = reducedProblemData.Dataset.Rows;
+      reducedProblemData.ValidationPercentage.Value = 0;
 
       double quality = PerformCrossValidation(reducedProblemData,
-                             SamplesStart.Value, SamplesStart.Value + reducedRows,
                              SvmType.Value, KernelType.Value,
                              Cost.Value, Nu.Value, Gamma.Value, Epsilon.Value, NumberOfFolds.Value);
@@ -160,6 +180,6 @@
     }
 
-    private Dataset CreateReducedDataset(IRandom random, Dataset dataset, double reductionRatio, int start, int end) {
-      int n = (int)((end - start) * reductionRatio);
+    private Dataset CreateReducedDataset(IRandom random, Dataset dataset, IEnumerable<int> rowIndices, double reductionRatio) {
+
       // must not make a fink:
       // => select n rows randomly from start..end
@@ -168,24 +188,28 @@
 
       // all possible rowIndexes from start..end
-      int[] rowIndexes = Enumerable.Range(start, end - start).ToArray();
+      int[] rowIndexArr = rowIndices.ToArray();
+      int n = (int)Math.Max(1.0, rowIndexArr.Length * reductionRatio);
 
       // knuth shuffle
-      for (int i = rowIndexes.Length - 1; i > 0; i--) {
+      for (int i = rowIndexArr.Length - 1; i > 0; i--) {
         int j = random.Next(0, i);
         // swap
-        int tmp = rowIndexes[i];
-        rowIndexes[i] = rowIndexes[j];
-        rowIndexes[j] = tmp;
+        int tmp = rowIndexArr[i];
+        rowIndexArr[i] = rowIndexArr[j];
+        rowIndexArr[j] = tmp;
       }
 
       // take the first n indexes (selected n rowIndexes from start..end)
       // now order by index
-      var orderedRandomIndexes = rowIndexes.Take(n).OrderBy(x => x).ToArray();
-
-      // now build a dataset collecting the rows from orderedRandomIndexes into the dataset starting at index start
-      double[,] reducedData = dataset.GetClonedData();
+      int[] orderedRandomIndexes =
+        rowIndexArr.Take(n)
+        .OrderBy(x => x)
+        .ToArray();
+
+      // now build a dataset containing only rows from orderedRandomIndexes 
+      double[,] reducedData = new double[n, dataset.Columns];
       for (int i = 0; i < n; i++) {
         for (int column = 0; column < dataset.Columns; column++) {
-          reducedData[start + i, column] = dataset[orderedRandomIndexes[i], column];
+          reducedData[i, column] = dataset[orderedRandomIndexes[i], column];
         }
       }
@@ -198,10 +222,10 @@
       double cost, double nu, double gamma, double epsilon,
       int nFolds) {
-      return PerformCrossValidation(problemData, problemData.TrainingSamplesStart.Value, problemData.TrainingSamplesEnd.Value, svmType, kernelType, cost, nu, gamma, epsilon, nFolds);
+      return PerformCrossValidation(problemData, problemData.TrainingIndizes, svmType, kernelType, cost, nu, gamma, epsilon, nFolds);
     }
 
     public static double PerformCrossValidation(
       DataAnalysisProblemData problemData,
-      int start, int end,
+      IEnumerable<int> rowIndices,
       string svmType, string kernelType,
       double cost, double nu, double gamma, double epsilon,
@@ -221,5 +245,5 @@
 
 
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, start, end);
+      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, rowIndices);
       SVM.RangeTransform rangeTransform = SVM.RangeTransform.Compute(problem);
       SVM.Problem scaledProblem = Scaling.Scale(rangeTransform, problem);
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModel.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModel.cs	(revision 5275)
@@ -36,8 +36,14 @@
   [StorableClass]
   [Item("SupportVectorMachineModel", "Represents a support vector machine model.")]
-  public class SupportVectorMachineModel : NamedItem, IDataAnalysisModel {
-    public SupportVectorMachineModel()
-      : base() {
+  public sealed class SupportVectorMachineModel : NamedItem, IDataAnalysisModel {
+    [StorableConstructor]
+    private SupportVectorMachineModel(bool deserializing) : base(deserializing) { }
+    private SupportVectorMachineModel(SupportVectorMachineModel original, Cloner cloner)
+      : base(original, cloner) {
+      // only using a shallow copy here! (gkronber)
+      this.model = original.model;
+      this.rangeTransform = original.rangeTransform;
     }
+    public SupportVectorMachineModel() : base() { }
 
     private SVM.Model model;
@@ -72,9 +78,10 @@
 
     public IEnumerable<double> GetEstimatedValues(DataAnalysisProblemData problemData, int start, int end) {
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, start, end);
+      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, Enumerable.Range(start, end - start));
       SVM.Problem scaledProblem = Scaling.Scale(RangeTransform, problem);
 
       return (from row in Enumerable.Range(0, scaledProblem.Count)
-              select SVM.Prediction.Predict(Model, scaledProblem.X[row])).ToList();
+              select SVM.Prediction.Predict(Model, scaledProblem.X[row]))
+              .ToList();
     }
 
@@ -130,9 +137,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      SupportVectorMachineModel clone = (SupportVectorMachineModel)base.Clone(cloner);
-      // beware we are only using a shallow copy here! (gkronber)
-      clone.model = model;
-      clone.rangeTransform = rangeTransform;
-      return clone;
+      return new SupportVectorMachineModel(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelCreator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelCreator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelCreator.cs	(revision 5275)
@@ -21,4 +21,7 @@
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -34,5 +37,5 @@
   [StorableClass]
   [Item("SupportVectorMachineModelCreator", "Represents an operator that creates a support vector machine model.")]
-  public class SupportVectorMachineModelCreator : SingleSuccessorOperator {
+  public sealed class SupportVectorMachineModelCreator : SingleSuccessorOperator {
     private const string DataAnalysisProblemDataParameterName = "DataAnalysisProblemData";
     private const string SvmTypeParameterName = "SvmType";
@@ -108,4 +111,10 @@
     #endregion
 
+    [StorableConstructor]
+    private SupportVectorMachineModelCreator(bool deserializing) : base(deserializing) { }
+    private SupportVectorMachineModelCreator(SupportVectorMachineModelCreator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SupportVectorMachineModelCreator(this, cloner);
+    }
     public SupportVectorMachineModelCreator()
       : base() {
@@ -125,6 +134,12 @@
 
     public override IOperation Apply() {
+      int start = SamplesStart.Value;
+      int end = SamplesEnd.Value;
+      IEnumerable<int> rows =
+        Enumerable.Range(start, end - start)
+        .Where(i => i < DataAnalysisProblemData.TestSamplesStart.Value || DataAnalysisProblemData.TestSamplesEnd.Value <= i);
+
       SupportVectorMachineModel model = TrainModel(DataAnalysisProblemData,
-                             SamplesStart.Value, SamplesEnd.Value,
+                             rows,
                              SvmType.Value, KernelType.Value,
                              Cost.Value, Nu.Value, Gamma.Value, Epsilon.Value);
@@ -138,10 +153,10 @@
       string svmType, string kernelType,
       double cost, double nu, double gamma, double epsilon) {
-      return TrainModel(problemData, problemData.TrainingSamplesStart.Value, problemData.TrainingSamplesEnd.Value, svmType, kernelType, cost, nu, gamma, epsilon);
+      return TrainModel(problemData, problemData.TrainingIndizes, svmType, kernelType, cost, nu, gamma, epsilon);
     }
 
     public static SupportVectorMachineModel TrainModel(
       DataAnalysisProblemData problemData,
-      int start, int end,
+      IEnumerable<int> trainingIndizes,
       string svmType, string kernelType,
       double cost, double nu, double gamma, double epsilon) {
@@ -160,5 +175,5 @@
 
 
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, start, end);
+      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, trainingIndizes);
       SVM.RangeTransform rangeTransform = SVM.RangeTransform.Compute(problem);
       SVM.Problem scaledProblem = Scaling.Scale(rangeTransform, problem);
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelEvaluator.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelEvaluator.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineModelEvaluator.cs	(revision 5275)
@@ -20,4 +20,7 @@
 #endregion
 
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -68,4 +71,11 @@
     }
     #endregion
+
+    [StorableConstructor]
+    protected SupportVectorMachineModelEvaluator(bool deserializing) : base(deserializing) { }
+    protected SupportVectorMachineModelEvaluator(SupportVectorMachineModelEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SupportVectorMachineModelEvaluator(this, cloner);
+    }
     public SupportVectorMachineModelEvaluator()
       : base() {
@@ -80,11 +90,14 @@
       int start = SamplesStart.Value;
       int end = SamplesEnd.Value;
+      IEnumerable<int> rows =
+        Enumerable.Range(start, end - start)
+        .Where(i => i < DataAnalysisProblemData.TestSamplesStart.Value || DataAnalysisProblemData.TestSamplesEnd.Value <= i);
 
-      ValuesParameter.ActualValue = new DoubleMatrix(Evaluate(SupportVectorMachineModel, DataAnalysisProblemData, start, end));
+      ValuesParameter.ActualValue = new DoubleMatrix(Evaluate(SupportVectorMachineModel, DataAnalysisProblemData, rows));
       return base.Apply();
     }
 
-    public static double[,] Evaluate(SupportVectorMachineModel model, DataAnalysisProblemData problemData, int start, int end) {
-      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, start, end);
+    public static double[,] Evaluate(SupportVectorMachineModel model, DataAnalysisProblemData problemData, IEnumerable<int> rowIndices) {
+      SVM.Problem problem = SupportVectorMachineUtil.CreateSvmProblem(problemData, rowIndices);
       SVM.Problem scaledProblem = model.RangeTransform.Scale(problem);
 
@@ -92,6 +105,8 @@
 
       double[,] values = new double[scaledProblem.Count, 2];
+      var rowEnumerator = rowIndices.GetEnumerator();
       for (int i = 0; i < scaledProblem.Count; i++) {
-        values[i, 0] = problemData.Dataset[start + i, targetVariableIndex];
+        rowEnumerator.MoveNext();
+        values[i, 0] = problemData.Dataset[rowEnumerator.Current, targetVariableIndex];
         values[i, 1] = SVM.Prediction.Predict(model.Model, scaledProblem.X[i]);
       }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineUtil.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineUtil.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/SupportVectorMachine/SupportVectorMachineUtil.cs	(revision 5275)
@@ -29,26 +29,27 @@
     /// </summary>
     /// <param name="problemData">The problem data to transform</param>
-    /// <param name="start">The index of the first row of <paramref name="problemData"/> to copy to the output.</param>
-    /// <param name="end">The last of the first row of <paramref name="problemData"/> to copy to the output.</param>
+    /// <param name="rowIndices">The rows of the dataset that should be contained in the resulting SVM-problem</param>
     /// <returns>A problem data type that can be used to train a support vector machine.</returns>
-    public static SVM.Problem CreateSvmProblem(DataAnalysisProblemData problemData, int start, int end) {
-      int rowCount = end - start;
-      var targetVector = problemData.Dataset.GetVariableValues(problemData.TargetVariable.Value, start, end);
+    public static SVM.Problem CreateSvmProblem(DataAnalysisProblemData problemData, IEnumerable<int> rowIndices) {
+      double[] targetVector =
+        problemData.Dataset.GetEnumeratedVariableValues(problemData.TargetVariable.Value, rowIndices)
+        .ToArray();
 
       SVM.Node[][] nodes = new SVM.Node[targetVector.Length][];
       List<SVM.Node> tempRow;
       int maxNodeIndex = 0;
-      for (int row = 0; row < rowCount; row++) {
+      int svmProblemRowIndex = 0;
+      foreach (int row in rowIndices) {
         tempRow = new List<SVM.Node>();
         foreach (var inputVariable in problemData.InputVariables.CheckedItems) {
           int col = problemData.Dataset.GetVariableIndex(inputVariable.Value.Value);
-          double value = problemData.Dataset[start + row, col];
+          double value = problemData.Dataset[row, col];
           if (!double.IsNaN(value)) {
-            int nodeIndex = col + 1; // make sure the smallest nodeIndex = 1
+            int nodeIndex = col + 1; // make sure the smallest nodeIndex is 1 (libSVM convention)
             tempRow.Add(new SVM.Node(nodeIndex, value));
             if (nodeIndex > maxNodeIndex) maxNodeIndex = nodeIndex;
           }
         }
-        nodes[row] = tempRow.OrderBy(x => x.Index).ToArray(); // make sure the values are sorted by node index
+        nodes[svmProblemRowIndex++] = tempRow.OrderBy(x => x.Index).ToArray(); // make sure the values are sorted by node index
       }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/ArithmeticExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/ArithmeticExpressionGrammar.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/ArithmeticExpressionGrammar.cs	(revision 5275)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -30,11 +31,15 @@
   [Item("ArithmeticExpressionGrammar", "Represents a grammar for functional expressions using only arithmetic operations.")]
   public class ArithmeticExpressionGrammar : DefaultSymbolicExpressionGrammar {
+
+    [StorableConstructor]
+    protected ArithmeticExpressionGrammar(bool deserializing) : base(deserializing) { }
+    protected ArithmeticExpressionGrammar(ArithmeticExpressionGrammar original, Cloner cloner) : base(original, cloner) { }
     public ArithmeticExpressionGrammar()
       : base() {
       Initialize();
     }
-
-    [StorableConstructor]
-    protected ArithmeticExpressionGrammar(bool deserializing) : base(deserializing) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ArithmeticExpressionGrammar(this, cloner);
+    }
 
     private void Initialize() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/BasicExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/BasicExpressionGrammar.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/BasicExpressionGrammar.cs	(revision 5275)
@@ -26,4 +26,5 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
+using HeuristicLab.Common;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   [StorableClass]
@@ -33,4 +34,14 @@
     private HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable variableSymbol;
 
+    [StorableConstructor]
+    protected BasicExpressionGrammar(bool deserializing) : base(deserializing) { }
+    protected BasicExpressionGrammar(BasicExpressionGrammar original, Cloner cloner)
+      : base(original, cloner) {
+      foreach (var symb in Symbols) {
+        var varSym = symb as HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable;
+        if (varSym != null) this.variableSymbol = varSym;
+        break;
+      }
+    }
     public BasicExpressionGrammar()
       : base() {
@@ -38,6 +49,7 @@
     }
 
-    [StorableConstructor]
-    protected BasicExpressionGrammar(bool deserializing) : base(deserializing) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BasicExpressionGrammar(this, cloner);
+    }
 
     private void Initialize() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/FullFunctionalExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/FullFunctionalExpressionGrammar.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/FullFunctionalExpressionGrammar.cs	(revision 5275)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -30,10 +31,15 @@
   [Item("FullFunctionalExpressionGrammar", "Represents a grammar for functional expressions using all available functions.")]
   public class FullFunctionalExpressionGrammar : DefaultSymbolicExpressionGrammar {
+    [StorableConstructor]
+    protected FullFunctionalExpressionGrammar(bool deserializing) : base(deserializing) { }
+    protected FullFunctionalExpressionGrammar(FullFunctionalExpressionGrammar original, Cloner cloner) : base(original, cloner) { }
     public FullFunctionalExpressionGrammar()
       : base() {
       Initialize();
     }
-    [StorableConstructor]
-    protected FullFunctionalExpressionGrammar(bool deserializing) : base(deserializing) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FullFunctionalExpressionGrammar(this, cloner);
+    }
 
     private void Initialize() {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SimpleArithmeticExpressionInterpreter.cs	(revision 5275)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -32,6 +33,5 @@
   [StorableClass]
   [Item("SimpleArithmeticExpressionInterpreter", "Interpreter for arithmetic symbolic expression trees including function calls.")]
-  // not thread safe!
-  public class SimpleArithmeticExpressionInterpreter : NamedItem, ISymbolicExpressionTreeInterpreter {
+  public sealed class SimpleArithmeticExpressionInterpreter : NamedItem, ISymbolicExpressionTreeInterpreter {
     private class OpCodes {
       public const byte Add = 1;
@@ -65,5 +65,4 @@
       public const byte Constant = 20;
       public const byte Arg = 21;
-      public const byte Differential = 22;
     }
 
@@ -90,15 +89,7 @@
       { typeof(Constant), OpCodes.Constant },
       { typeof(Argument), OpCodes.Arg },
-      { typeof(DifferentialVariable), OpCodes.Differential},
     };
     private const int ARGUMENT_STACK_SIZE = 1024;
 
-    private Dataset dataset;
-    private int row;
-    private Instruction[] code;
-    private int pc;
-    private double[] argumentStack = new double[ARGUMENT_STACK_SIZE];
-    private int argStackPointer;
-
     public override bool CanChangeName {
       get { return false; }
@@ -108,4 +99,11 @@
     }
 
+    [StorableConstructor]
+    private SimpleArithmeticExpressionInterpreter(bool deserializing) : base(deserializing) { }
+    private SimpleArithmeticExpressionInterpreter(SimpleArithmeticExpressionInterpreter original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SimpleArithmeticExpressionInterpreter(this, cloner);
+    }
+
     public SimpleArithmeticExpressionInterpreter()
       : base() {
@@ -113,28 +111,171 @@
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(SymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
-      this.dataset = dataset;
       var compiler = new SymbolicExpressionTreeCompiler();
-      compiler.AddInstructionPostProcessingHook(PostProcessInstruction);
-      code = compiler.Compile(tree, MapSymbolToOpCode);
-      foreach (var row in rows) {
-        this.row = row;
-        pc = 0;
-        argStackPointer = 0;
-        yield return Evaluate();
-      }
-    }
-
-    private Instruction PostProcessInstruction(Instruction instr) {
-      if (instr.opCode == OpCodes.Variable) {
-        var variableTreeNode = instr.dynamicNode as VariableTreeNode;
-        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
-      } else if (instr.opCode == OpCodes.LagVariable) {
-        var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
-        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
-      } else if (instr.opCode == OpCodes.Differential) {
-        var variableTreeNode = instr.dynamicNode as DifferentialVariableTreeNode;
-        instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
-      }
-      return instr;
+      Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);
+
+      for (int i = 0; i < code.Length; i++) {
+        Instruction instr = code[i];
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = instr.dynamicNode as VariableTreeNode;
+          instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
+          code[i] = instr;
+        } else if (instr.opCode == OpCodes.LagVariable) {
+          var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
+          instr.iArg0 = (ushort)dataset.GetVariableIndex(variableTreeNode.VariableName);
+          code[i] = instr;
+        }
+      }
+
+      double[] argumentStack = new double[ARGUMENT_STACK_SIZE];
+      foreach (var rowEnum in rows) {
+        int row = rowEnum;
+        int pc = 0;
+        int argStackPointer = 0;
+        yield return Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+      }
+    }
+
+    private double Evaluate(Dataset dataset, ref int row, Instruction[] code, ref int pc, double[] argumentStack, ref int argStackPointer) {
+      Instruction currentInstr = code[pc++];
+      switch (currentInstr.opCode) {
+        case OpCodes.Add: {
+            double s = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s += Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            return s;
+          }
+        case OpCodes.Sub: {
+            double s = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s -= Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            if (currentInstr.nArguments == 1) s = -s;
+            return s;
+          }
+        case OpCodes.Mul: {
+            double p = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p *= Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            return p;
+          }
+        case OpCodes.Div: {
+            double p = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p /= Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            if (currentInstr.nArguments == 1) p = 1.0 / p;
+            return p;
+          }
+        case OpCodes.Average: {
+            double sum = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              sum += Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            return sum / currentInstr.nArguments;
+          }
+        case OpCodes.Cos: {
+            return Math.Cos(Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer));
+          }
+        case OpCodes.Sin: {
+            return Math.Sin(Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer));
+          }
+        case OpCodes.Tan: {
+            return Math.Tan(Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer));
+          }
+        case OpCodes.Exp: {
+            return Math.Exp(Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer));
+          }
+        case OpCodes.Log: {
+            return Math.Log(Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer));
+          }
+        case OpCodes.IfThenElse: {
+            double condition = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            double result;
+            if (condition > 0.0) {
+              result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer); SkipBakedCode(code, ref pc);
+            } else {
+              SkipBakedCode(code, ref pc); result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            return result;
+          }
+        case OpCodes.AND: {
+            double result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result <= 0.0) SkipBakedCode(code, ref pc);
+              else {
+                result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+              }
+            }
+            return result <= 0.0 ? -1.0 : 1.0;
+          }
+        case OpCodes.OR: {
+            double result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result > 0.0) SkipBakedCode(code, ref pc);
+              else {
+                result = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+              }
+            }
+            return result > 0.0 ? 1.0 : -1.0;
+          }
+        case OpCodes.NOT: {
+            return -Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+          }
+        case OpCodes.GT: {
+            double x = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            double y = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            if (x > y) return 1.0;
+            else return -1.0;
+          }
+        case OpCodes.LT: {
+            double x = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            double y = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            if (x < y) return 1.0;
+            else return -1.0;
+          }
+        case OpCodes.Call: {
+            // evaluate sub-trees
+            // push on argStack in reverse order 
+            for (int i = 0; i < currentInstr.nArguments; i++) {
+              argumentStack[argStackPointer + currentInstr.nArguments - i] = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+            }
+            argStackPointer += currentInstr.nArguments;
+
+            // save the pc
+            int nextPc = pc;
+            // set pc to start of function  
+            pc = currentInstr.iArg0;
+            // evaluate the function
+            double v = Evaluate(dataset, ref row, code, ref pc, argumentStack, ref argStackPointer);
+
+            // decrease the argument stack pointer by the number of arguments pushed
+            // to set the argStackPointer back to the original location
+            argStackPointer -= currentInstr.nArguments;
+
+            // restore the pc => evaluation will continue at point after my subtrees  
+            pc = nextPc;
+            return v;
+          }
+        case OpCodes.Arg: {
+            return argumentStack[argStackPointer - currentInstr.iArg0];
+          }
+        case OpCodes.Variable: {
+            var variableTreeNode = currentInstr.dynamicNode as VariableTreeNode;
+            return dataset[row, currentInstr.iArg0] * variableTreeNode.Weight;
+          }
+        case OpCodes.LagVariable: {
+            var laggedVariableTreeNode = currentInstr.dynamicNode as LaggedVariableTreeNode;
+            int actualRow = row + laggedVariableTreeNode.Lag;
+            if (actualRow < 0 || actualRow >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);
+            return dataset[actualRow, currentInstr.iArg0] * laggedVariableTreeNode.Weight;
+          }
+        case OpCodes.Constant: {
+            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
+            return constTreeNode.Value;
+          }
+        default: throw new NotSupportedException();
+      }
     }
 
@@ -146,156 +287,6 @@
     }
 
-    private double Evaluate() {
-      Instruction currentInstr = code[pc++];
-      switch (currentInstr.opCode) {
-        case OpCodes.Add: {
-            double s = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s += Evaluate();
-            }
-            return s;
-          }
-        case OpCodes.Sub: {
-            double s = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s -= Evaluate();
-            }
-            if (currentInstr.nArguments == 1) s = -s;
-            return s;
-          }
-        case OpCodes.Mul: {
-            double p = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p *= Evaluate();
-            }
-            return p;
-          }
-        case OpCodes.Div: {
-            double p = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p /= Evaluate();
-            }
-            if (currentInstr.nArguments == 1) p = 1.0 / p;
-            return p;
-          }
-        case OpCodes.Average: {
-            double sum = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              sum += Evaluate();
-            }
-            return sum / currentInstr.nArguments;
-          }
-        case OpCodes.Cos: {
-            return Math.Cos(Evaluate());
-          }
-        case OpCodes.Sin: {
-            return Math.Sin(Evaluate());
-          }
-        case OpCodes.Tan: {
-            return Math.Tan(Evaluate());
-          }
-        case OpCodes.Exp: {
-            return Math.Exp(Evaluate());
-          }
-        case OpCodes.Log: {
-            return Math.Log(Evaluate());
-          }
-        case OpCodes.IfThenElse: {
-            double condition = Evaluate();
-            double result;
-            if (condition > 0.0) {
-              result = Evaluate(); SkipBakedCode();
-            } else {
-              SkipBakedCode(); result = Evaluate();
-            }
-            return result;
-          }
-        case OpCodes.AND: {
-            double result = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result <= 0.0) SkipBakedCode();
-              else {
-                result = Evaluate();
-              }
-            }
-            return result <= 0.0 ? -1.0 : 1.0;
-          }
-        case OpCodes.OR: {
-            double result = Evaluate();
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result > 0.0) SkipBakedCode();
-              else {
-                result = Evaluate();
-              }
-            }
-            return result > 0.0 ? 1.0 : -1.0;
-          }
-        case OpCodes.NOT: {
-            return -Evaluate();
-          }
-        case OpCodes.GT: {
-            double x = Evaluate();
-            double y = Evaluate();
-            if (x > y) return 1.0;
-            else return -1.0;
-          }
-        case OpCodes.LT: {
-            double x = Evaluate();
-            double y = Evaluate();
-            if (x < y) return 1.0;
-            else return -1.0;
-          }
-        case OpCodes.Call: {
-            // evaluate sub-trees
-            // push on argStack in reverse order 
-            for (int i = 0; i < currentInstr.nArguments; i++) {
-              argumentStack[argStackPointer + currentInstr.nArguments - i] = Evaluate();
-            }
-            argStackPointer += currentInstr.nArguments;
-
-            // save the pc
-            int nextPc = pc;
-            // set pc to start of function  
-            pc = currentInstr.iArg0;
-            // evaluate the function
-            double v = Evaluate();
-
-            // decrease the argument stack pointer by the number of arguments pushed
-            // to set the argStackPointer back to the original location
-            argStackPointer -= currentInstr.nArguments;
-
-            // restore the pc => evaluation will continue at point after my subtrees  
-            pc = nextPc;
-            return v;
-          }
-        case OpCodes.Arg: {
-            return argumentStack[argStackPointer - currentInstr.iArg0];
-          }
-        case OpCodes.Variable: {
-            var variableTreeNode = currentInstr.dynamicNode as VariableTreeNode;
-            return dataset[row, currentInstr.iArg0] * variableTreeNode.Weight;
-          }
-        case OpCodes.LagVariable: {
-            var lagVariableTreeNode = currentInstr.dynamicNode as LaggedVariableTreeNode;
-            int actualRow = row + lagVariableTreeNode.Lag;
-            if (actualRow < 0 || actualRow >= dataset.Rows) throw new ArgumentException("Out of range access to dataset row: " + row);
-            return dataset[actualRow, currentInstr.iArg0] * lagVariableTreeNode.Weight;
-          }
-        case OpCodes.Differential: {
-            var diffTreeNode = currentInstr.dynamicNode as DifferentialVariableTreeNode;
-            if (row < 2 || row >= dataset.Rows - 2) throw new ArgumentException("Out of range access to dataset row: " + row);
-            return (-dataset[row + 2, currentInstr.iArg0] + 8 * dataset[row + 1, currentInstr.iArg0] - 8 * dataset[row - 1, currentInstr.iArg0] + dataset[row - 2, currentInstr.iArg0]) * (1.0/12.0) * diffTreeNode.Weight;
-          }
-
-        case OpCodes.Constant: {
-            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
-            return constTreeNode.Value;
-          }
-        default: throw new NotSupportedException();
-      }
-    }
-
     // skips a whole branch
-    protected void SkipBakedCode() {
+    private void SkipBakedCode(Instruction[] code, ref int pc) {
       int i = 1;
       while (i > 0) {
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/SymbolicSimplifier.cs	(revision 5275)
@@ -354,8 +354,7 @@
       while (sum.SubTrees.Count > 0) sum.RemoveSubTree(0);
       var groupedVarNodes = from node in subtrees.OfType<VariableTreeNode>()
-                            where node.Symbol.Name == "Variable"
                             group node by node.VariableName into g
                             select g;
-      var unchangedSubTrees = subtrees.Where(t => t.Symbol.Name != "Variable");
+      var unchangedSubTrees = subtrees.Where(t => !(t is VariableTreeNode));
 
       foreach (var variableNodeGroup in groupedVarNodes) {
@@ -430,10 +429,8 @@
       while (prod.SubTrees.Count > 0) prod.RemoveSubTree(0);
       var groupedVarNodes = from node in subtrees.OfType<VariableTreeNode>()
-                            where node.Symbol.Name == "Variable"
                             group node by node.VariableName into g
                             orderby g.Count()
                             select g;
       var constantProduct = (from node in subtrees.OfType<VariableTreeNode>()
-                             where node.Symbol.Name == "Variable"
                              select node.Weight)
                             .Concat(from node in subtrees.OfType<ConstantTreeNode>()
@@ -443,5 +440,5 @@
 
       var unchangedSubTrees = from tree in subtrees
-                              where !(tree is VariableTreeNode && tree.Symbol.Name == "Variable")
+                              where !(tree is VariableTreeNode)
                               where !(tree is ConstantTreeNode)
                               select tree;
@@ -485,10 +482,9 @@
       } else if (IsAddition(x)) {
         // (x0 + x1 + .. + xn) * -1 => (-x0 + -x1 + .. + -xn)        
-        foreach (var subTree in x.SubTrees) {
-          Negate(subTree);
-        }
+        for (int i = 0; i < x.SubTrees.Count; i++)
+          x.SubTrees[i] = Negate(x.SubTrees[i]);
       } else if (IsMultiplication(x) || IsDivision(x)) {
         // x0 * x1 * .. * xn * -1 => x0 * x1 * .. * -xn
-        Negate(x.SubTrees.Last()); // last is maybe a constant, prefer to negate the constant
+        x.SubTrees[x.SubTrees.Count - 1] = Negate(x.SubTrees.Last()); // last is maybe a constant, prefer to negate the constant
       } else {
         // any other function
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Addition.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Addition.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Addition.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Addition", "Symbol that represents the + operator.")]
   public sealed class Addition : Symbol {
+    [StorableConstructor]
+    private Addition(bool deserializing) : base(deserializing) { }
+    private Addition(Addition original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Addition(this, cloner);
+    }
     public Addition() : base("Addition", "Symbol that represents the + operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/And.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/And.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/And.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("And", "Symbol that represents the boolean AND operator.")]
   public sealed class And : Symbol {
+    [StorableConstructor]
+    private And(bool deserializing) : base(deserializing) { }
+    private And(And original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new And(this, cloner);
+    }
     public And() : base("And", "Symbol that represents the boolean AND operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Average.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Average.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Average.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Average", "Symbol that represents the average (arithmetic mean) function.")]
   public sealed class Average : Symbol {
+    [StorableConstructor]
+    private Average(bool deserializing) : base(deserializing) { }
+    private Average(Average original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Average(this, cloner);
+    }
     public Average() : base("Average", "Symbol that represents the average (arithmetic mean) function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Constant.cs	(revision 5275)
@@ -54,10 +54,10 @@
     }
     [Storable]
-    private double manipulatorNu;
-    public double ManipulatorNu {
-      get { return manipulatorNu; }
+    private double manipulatorMu;
+    public double ManipulatorMu {
+      get { return manipulatorMu; }
       set {
-        if (value != manipulatorNu) {
-          manipulatorNu = value;
+        if (value != manipulatorMu) {
+          manipulatorMu = value;
           OnChanged(EventArgs.Empty);
         }
@@ -77,7 +77,16 @@
     }
     #endregion
+    [StorableConstructor]
+    private Constant(bool deserializing) : base(deserializing) { }
+    private Constant(Constant original, Cloner cloner)
+      : base(original, cloner) {
+      minValue = original.minValue;
+      maxValue = original.maxValue;
+      manipulatorMu = original.manipulatorMu;
+      manipulatorSigma = original.manipulatorSigma;
+    }
     public Constant()
       : base("Constant", "Represents a constant value.") {
-      manipulatorNu = 0.0;
+      manipulatorMu = 0.0;
       manipulatorSigma = 1.0;
       minValue = -20.0;
@@ -90,10 +99,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      Constant clone = (Constant)base.Clone(cloner);
-      clone.minValue = minValue;
-      clone.maxValue = maxValue;
-      clone.manipulatorNu = manipulatorNu;
-      clone.manipulatorSigma = manipulatorSigma;
-      return clone;
+      return new Constant(this, cloner);
     }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/ConstantTreeNode.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -38,12 +39,13 @@
     }
 
-    private ConstantTreeNode() : base() { }
+    [StorableConstructor]
+    private ConstantTreeNode(bool deserializing) : base(deserializing) { }
 
-    // copy constructor
-    private ConstantTreeNode(ConstantTreeNode original)
-      : base(original) {
+    private ConstantTreeNode(ConstantTreeNode original, Cloner cloner)
+      : base(original, cloner) {
       constantValue = original.constantValue;
     }
 
+    private ConstantTreeNode() : base() { }
     public ConstantTreeNode(Constant constantSymbol) : base(constantSymbol) { }
 
@@ -61,10 +63,10 @@
     public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
       base.ShakeLocalParameters(random, shakingFactor);
-      double x = NormalDistributedRandom.NextDouble(random, Symbol.ManipulatorNu, Symbol.ManipulatorSigma);
+      double x = NormalDistributedRandom.NextDouble(random, Symbol.ManipulatorMu, Symbol.ManipulatorSigma);
       Value = Value + x * shakingFactor;
     }
 
-    public override object Clone() {
-      return new ConstantTreeNode(this);
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantTreeNode(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Cosine.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Cosine.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Cosine.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Cosine", "Symbol that represents the cosine function.")]
   public sealed class Cosine : Symbol {
+    [StorableConstructor]
+    private Cosine(bool deserializing) : base(deserializing) { }
+    private Cosine(Cosine original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Cosine(this, cloner);
+    }
     public Cosine() : base("Cosine", "Symbol that represents the cosine function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariable.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariable.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariable.cs	(revision 5275)
@@ -28,4 +28,9 @@
   [Item("DifferentialVariable", "Represents the differential of a variable value.")]
   public sealed class DifferentialVariable : Variable {
+    [StorableConstructor]
+    private DifferentialVariable(bool deserializing) : base(deserializing) { }
+    private DifferentialVariable(DifferentialVariable original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public DifferentialVariable()
       : base("DifferentialVariable", "Represents the differential of a variable value.") {
@@ -35,8 +40,6 @@
       return new DifferentialVariableTreeNode(this);
     }
-
     public override IDeepCloneable Clone(Cloner cloner) {
-      DifferentialVariable clone = (DifferentialVariable)base.Clone(cloner);
-      return clone;
+      return new DifferentialVariable(this, cloner);
     }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariableTreeNode.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariableTreeNode.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/DifferentialVariableTreeNode.cs	(revision 5275)
@@ -23,4 +23,5 @@
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Common;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols {
   [StorableClass]
@@ -30,18 +31,17 @@
     }
 
+    [StorableConstructor]
+    protected DifferentialVariableTreeNode(bool deserializing) : base(deserializing) { }
+    protected DifferentialVariableTreeNode(DifferentialVariableTreeNode original, Cloner cloner)
+      : base(original, cloner) {
+    }
     private DifferentialVariableTreeNode() { }
-
-    // copy constructor
-    private DifferentialVariableTreeNode(DifferentialVariableTreeNode original)
-      : base(original) {
-    }
 
     public DifferentialVariableTreeNode(DifferentialVariable differentialSymbol) : base(differentialSymbol) { }
 
 
-    public override object Clone() {
-      return new DifferentialVariableTreeNode(this);
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DifferentialVariableTreeNode(this, cloner);
     }
-
   }
 }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Division.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Division.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Division.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Division", "Symbol that represents the / operator.")]
   public sealed class Division : Symbol {
+    [StorableConstructor]
+    private Division(bool deserializing) : base(deserializing) { }
+    private Division(Division original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Division(this, cloner);
+    }
     public Division() : base("Division", "Symbol that represents the / operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Exponential.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Exponential.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Exponential.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Exponential", "Symbol that represents the exponential function.")]
   public sealed class Exponential : Symbol {
+    [StorableConstructor]
+    private Exponential(bool deserializing) : base(deserializing) { }
+    private Exponential(Exponential original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Exponential(this, cloner);
+    }
     public Exponential() : base("Exponential", "Symbol that represents the exponential function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/GreaterThan.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/GreaterThan.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/GreaterThan.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("GreaterThan", "Symbol that represents a greater than relation.")]
   public sealed class GreaterThan : Symbol {
+    [StorableConstructor]
+    private GreaterThan(bool deserializing) : base(deserializing) { }
+    private GreaterThan(GreaterThan original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GreaterThan(this, cloner);
+    }
     public GreaterThan() : base("GreaterThan", "Symbol that represents a greater than relation.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/IfThenElse.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/IfThenElse.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/IfThenElse.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("IfThenElse", "Symbol that represents a conditional operator.")]
   public sealed class IfThenElse : Symbol {
+    [StorableConstructor]
+    private IfThenElse(bool deserializing) : base(deserializing) { }
+    private IfThenElse(IfThenElse original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IfThenElse(this, cloner);
+    }
     public IfThenElse() : base("IfThenElse", "Symbol that represents a conditional operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariable.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariable.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariable.cs	(revision 5275)
@@ -40,4 +40,11 @@
       set { maxLag = value; }
     }
+    [StorableConstructor]
+    private LaggedVariable(bool deserializing) : base(deserializing) { }
+    private LaggedVariable(LaggedVariable original, Cloner cloner)
+      : base(original, cloner) {
+      minLag = original.minLag;
+      maxLag = original.maxLag;
+    }
     public LaggedVariable()
       : base("LaggedVariable", "Represents a variable value with a time offset.") {
@@ -50,8 +57,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      LaggedVariable clone = (LaggedVariable)base.Clone(cloner);
-      clone.minLag = minLag;
-      clone.maxLag = maxLag;
-      return clone;
+      return new LaggedVariable(this, cloner);
     }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariableTreeNode.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariableTreeNode.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LaggedVariableTreeNode.cs	(revision 5275)
@@ -21,4 +21,5 @@
 
 using System;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -36,11 +37,11 @@
     }
 
-    private LaggedVariableTreeNode() { }
-
-    // copy constructor
-    private LaggedVariableTreeNode(LaggedVariableTreeNode original)
-      : base(original) {
+    [StorableConstructor]
+    private LaggedVariableTreeNode(bool deserializing) : base(deserializing) { }
+    private LaggedVariableTreeNode(LaggedVariableTreeNode original, Cloner cloner)
+      : base(original, cloner) {
       lag = original.lag;
     }
+    private LaggedVariableTreeNode() { }
 
     public LaggedVariableTreeNode(LaggedVariable variableSymbol) : base(variableSymbol) { }
@@ -62,7 +63,6 @@
     }
 
-
-    public override object Clone() {
-      return new LaggedVariableTreeNode(this);
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LaggedVariableTreeNode(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LessThan.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LessThan.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/LessThan.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("LessThan", "Symbol that represents a less than relation.")]
   public sealed class LessThan : Symbol {
+    [StorableConstructor]
+    private LessThan(bool deserializing) : base(deserializing) { }
+    private LessThan(LessThan original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LessThan(this, cloner);
+    }
     public LessThan() : base("LessThan", "Symbol that represents a less than relation.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Logarithm.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Logarithm.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Logarithm.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Logarithm", "Symbol that represents the logarithm function.")]
   public sealed class Logarithm : Symbol {
+    [StorableConstructor]
+    private Logarithm(bool deserializing) : base(deserializing) { }
+    private Logarithm(Logarithm original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Logarithm(this, cloner);
+    }
     public Logarithm() : base("Logarithm", "Symbol that represents the logarithm function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Multiplication.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Multiplication.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Multiplication.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Multiplication", "Symbol that represents the * operator.")]
   public sealed class Multiplication : Symbol {
+    [StorableConstructor]
+    private Multiplication(bool deserializing) : base(deserializing) { }
+    private Multiplication(Multiplication original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Multiplication(this, cloner);
+    }
     public Multiplication() : base("Multiplication", "Symbol that represents the * operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Not.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Not.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Not.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Not", "Symbol that represents the boolean NOT operator.")]
   public sealed class Not : Symbol {
+    [StorableConstructor]
+    private Not(bool deserializing) : base(deserializing) { }
+    private Not(Not original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Not(this, cloner);
+    }
     public Not() : base("Not", "Symbol that represents the boolean NOT operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Or.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Or.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Or.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Or", "Symbol that represents the boolean OR operator.")]
   public sealed class Or : Symbol {
+    [StorableConstructor]
+    private Or(bool deserializing) : base(deserializing) { }
+    private Or(Or original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Or(this, cloner);
+    }
     public Or() : base("Or", "Symbol that represents the boolean OR operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Sine.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Sine.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Sine.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Sine", "Symbol that represents the sine function.")]
   public sealed class Sine : Symbol {
+    [StorableConstructor]
+    private Sine(bool deserializing) : base(deserializing) { }
+    private Sine(Sine original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Sine(this, cloner);
+    }
     public Sine() : base("Sine", "Symbol that represents the sine function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Subtraction.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Subtraction.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Subtraction.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Subtraction", "Symbol that represents the - operator.")]
   public sealed class Subtraction : Symbol {
+    [StorableConstructor]
+    private Subtraction(bool deserializing) : base(deserializing) { }
+    private Subtraction(Subtraction original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Subtraction(this, cloner);
+    }
     public Subtraction() : base("Subtraction", "Symbol that represents the - operator.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Tangent.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Tangent.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Tangent.cs	(revision 5275)
@@ -20,4 +20,5 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
@@ -27,4 +28,10 @@
   [Item("Tangent", "Symbol that represents the tangent trigonometric function.")]
   public sealed class Tangent : Symbol {
+    [StorableConstructor]
+    private Tangent(bool deserializing) : base(deserializing) { }
+    private Tangent(Tangent original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Tangent(this, cloner);
+    }
     public Tangent() : base("Tangent", "Symbol that represents the tangent trigonometric function.") { }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/Variable.cs	(revision 5275)
@@ -33,10 +33,10 @@
     #region Properties
     [Storable]
-    private double weightNu;
-    public double WeightNu {
-      get { return weightNu; }
+    private double weightMu;
+    public double WeightMu {
+      get { return weightMu; }
       set {
-        if (value != weightNu) {
-          weightNu = value;
+        if (value != weightMu) {
+          weightMu = value;
           OnChanged(EventArgs.Empty);
         }
@@ -56,10 +56,10 @@
     }
     [Storable]
-    private double weightManipulatorNu;
-    public double WeightManipulatorNu {
-      get { return weightManipulatorNu; }
+    private double weightManipulatorMu;
+    public double WeightManipulatorMu {
+      get { return weightManipulatorMu; }
       set {
-        if (value != weightManipulatorNu) {
-          weightManipulatorNu = value;
+        if (value != weightManipulatorMu) {
+          weightManipulatorMu = value;
           OnChanged(EventArgs.Empty);
         }
@@ -90,10 +90,22 @@
     }
     #endregion
+    [StorableConstructor]
+    protected Variable(bool deserializing) : base(deserializing) {
+      variableNames = new List<string>();
+    }
+    protected Variable(Variable original, Cloner cloner)
+      : base(original, cloner) {
+      weightMu = original.weightMu;
+      weightSigma = original.weightSigma;
+      variableNames = new List<string>(original.variableNames);
+      weightManipulatorMu = original.weightManipulatorMu;
+      weightManipulatorSigma = original.weightManipulatorSigma;
+    }
     public Variable() : this("Variable", "Represents a variable value.") { }
     public Variable(string name, string description)
       : base(name, description) {
-      weightNu = 1.0;
+      weightMu = 1.0;
       weightSigma = 1.0;
-      weightManipulatorNu = 0.0;
+      weightManipulatorMu = 0.0;
       weightManipulatorSigma = 1.0;
       variableNames = new List<string>();
@@ -105,11 +117,5 @@
 
     public override IDeepCloneable Clone(Cloner cloner) {
-      Variable clone = (Variable)base.Clone(cloner);
-      clone.weightNu = weightNu;
-      clone.weightSigma = weightSigma;
-      clone.variableNames = new List<string>(variableNames);
-      clone.weightManipulatorNu = weightManipulatorNu;
-      clone.weightManipulatorSigma = weightManipulatorSigma;
-      return clone;
+      return new Variable(this, cloner);
     }
   }
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/Symbols/VariableTreeNode.cs	(revision 5275)
@@ -20,6 +20,6 @@
 #endregion
 
+using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Common;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -44,14 +44,12 @@
     }
 
-
-    protected VariableTreeNode() { }
-
-    // copy constructor
-    protected VariableTreeNode(VariableTreeNode original)
-      : base(original) {
+    [StorableConstructor]
+    protected VariableTreeNode(bool deserializing) : base(deserializing) { }
+    protected VariableTreeNode(VariableTreeNode original, Cloner cloner)
+      : base(original, cloner) {
       weight = original.weight;
       variableName = original.variableName;
     }
-
+    protected VariableTreeNode() { }
     public VariableTreeNode(Variable variableSymbol) : base(variableSymbol) { }
 
@@ -64,5 +62,5 @@
     public override void ResetLocalParameters(IRandom random) {
       base.ResetLocalParameters(random);
-      weight = NormalDistributedRandom.NextDouble(random, Symbol.WeightNu, Symbol.WeightSigma);
+      weight = NormalDistributedRandom.NextDouble(random, Symbol.WeightMu, Symbol.WeightSigma);
       variableName = Symbol.VariableNames.SelectRandom(random);
     }
@@ -70,12 +68,11 @@
     public override void ShakeLocalParameters(IRandom random, double shakingFactor) {
       base.ShakeLocalParameters(random, shakingFactor);
-      double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorNu, Symbol.WeightManipulatorSigma);
+      double x = NormalDistributedRandom.NextDouble(random, Symbol.WeightManipulatorMu, Symbol.WeightManipulatorSigma);
       weight = weight + x * shakingFactor;
       variableName = Symbol.VariableNames.SelectRandom(random);
     }
 
-
-    public override object Clone() {
-      return new VariableTreeNode(this);
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new VariableTreeNode(this, cloner);
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/VariableFrequencyAnalyser.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/VariableFrequencyAnalyser.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Symbolic/VariableFrequencyAnalyser.cs	(revision 5275)
@@ -22,4 +22,5 @@
 using System.Collections.Generic;
 using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
@@ -61,4 +62,9 @@
     }
     #endregion
+    [StorableConstructor]
+    protected VariableFrequencyAnalyser(bool deserializing) : base(deserializing) { }
+    protected VariableFrequencyAnalyser(VariableFrequencyAnalyser original, Cloner cloner)
+      : base(original, cloner) {
+    }
     public VariableFrequencyAnalyser()
       : base() {
@@ -69,5 +75,5 @@
 
     public override IOperation Apply() {
-      var inputVariables = DataAnalysisProblemData.InputVariables.Select(x => x.Value);
+      var inputVariables = DataAnalysisProblemData.InputVariables.CheckedItems.Select(x => x.Value.Value);
       if (VariableFrequencies == null) {
         VariableFrequencies = new DoubleMatrix(0, 1, inputVariables);
@@ -80,5 +86,5 @@
         VariableFrequencies[lastRowIndex, columnIndex] = pair.Value;
       }
-      return null;
+      return base.Apply();
     }
 
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/TableFileParser.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/TableFileParser.cs	(revision 5275)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/TableFileParser.cs	(revision 5275)
@@ -0,0 +1,375 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class TableFileParser {
+    private const int BUFFER_SIZE = 1024;
+    private readonly char[] POSSIBLE_SEPARATORS = new char[] { ',', ';', '\t' };
+    private const string VARIABLENAMES = "VARIABLENAMES";
+    private Tokenizer tokenizer;
+    private List<string> variableNames;
+    private List<List<double>> rowValues;
+
+    private int rows;
+    public int Rows {
+      get { return rows; }
+      set { rows = value; }
+    }
+
+    private int columns;
+    public int Columns {
+      get { return columns; }
+      set { columns = value; }
+    }
+
+    private double[,] values;
+    public double[,] Values {
+      get {
+        return values;
+      }
+    }
+
+    public IEnumerable<string> VariableNames {
+      get {
+        if (variableNames.Count > 0) return variableNames;
+        else {
+          string[] names = new string[columns];
+          for (int i = 0; i < names.Length; i++) {
+            names[i] = "X" + i.ToString("000");
+          }
+          return names;
+        }
+      }
+    }
+
+    public TableFileParser() {
+      rowValues = new List<List<double>>();
+      variableNames = new List<string>();
+    }
+
+    private void Reset() {
+      variableNames.Clear();
+      rowValues.Clear();
+    }
+
+    public void Parse(string fileName) {
+      NumberFormatInfo numberFormat;
+      char separator;
+      DetermineFileFormat(fileName, out numberFormat, out separator);
+      using (StreamReader reader = new StreamReader(fileName)) {
+        tokenizer = new Tokenizer(reader, numberFormat, separator);
+        // parse the file
+        Parse();
+      }
+
+      // translate the list of samples into a DoubleMatrixData item
+      rows = rowValues.Count;
+      columns = rowValues[0].Count;
+      values = new double[rows, columns];
+
+      int rowIndex = 0;
+      int columnIndex = 0;
+      foreach (List<double> row in rowValues) {
+        columnIndex = 0;
+        foreach (double element in row) {
+          values[rowIndex, columnIndex++] = element;
+        }
+        rowIndex++;
+      }
+    }
+
+    private void DetermineFileFormat(string fileName, out NumberFormatInfo numberFormat, out char separator) {
+      using (StreamReader reader = new StreamReader(fileName)) {
+        // skip first line
+        reader.ReadLine();
+        // read a block
+        char[] buffer = new char[BUFFER_SIZE];
+        int charsRead = reader.ReadBlock(buffer, 0, BUFFER_SIZE);
+        // count frequency of special characters
+        Dictionary<char, int> charCounts = buffer.Take(charsRead)
+          .GroupBy(c => c)
+          .ToDictionary(g => g.Key, g => g.Count());
+
+        // depending on the characters occuring in the block 
+        // we distinghish a number of different cases based on the the following rules:
+        // many points => it must be English number format, the other frequently occuring char is the separator
+        // no points but many commas => this is the problematic case. Either German format (real numbers) or English format (only integer numbers) with ',' as separator
+        //   => check the line in more detail:
+        //            English: 0, 0, 0, 0
+        //            German:  0,0 0,0 0,0 ...
+        //            => if commas are followed by space => English format
+        // no points no commas => English format (only integer numbers) use the other frequently occuring char as separator
+        // in all cases only treat ' ' as separator if no other separator is possible (spaces can also occur additionally to separators)
+        if (OccurrencesOf(charCounts, '.') > 10) {
+          numberFormat = NumberFormatInfo.InvariantInfo;
+          separator = POSSIBLE_SEPARATORS
+            .Where(c => OccurrencesOf(charCounts, c) > 10)
+            .OrderBy(c => -OccurrencesOf(charCounts, c))
+            .DefaultIfEmpty(' ')
+            .First();
+        } else if (OccurrencesOf(charCounts, ',') > 10) {
+          // no points and many commas
+          int countCommaNonDigitPairs = 0;
+          for (int i = 0; i < charsRead - 1; i++) {
+            if (buffer[i] == ',' && !Char.IsDigit(buffer[i + 1])) {
+              countCommaNonDigitPairs++;
+            }
+          }
+          if (countCommaNonDigitPairs > 10) {
+            // English format (only integer values) with ',' as separator
+            numberFormat = NumberFormatInfo.InvariantInfo;
+            separator = ',';
+          } else {
+            char[] disallowedSeparators = new char[] { ',' };
+            // German format (real values)
+            numberFormat = NumberFormatInfo.GetInstance(new CultureInfo("de-DE"));
+            separator = POSSIBLE_SEPARATORS
+              .Except(disallowedSeparators)
+              .Where(c => OccurrencesOf(charCounts, c) > 10)
+              .OrderBy(c => -OccurrencesOf(charCounts, c))
+              .DefaultIfEmpty(' ')
+              .First();
+          }
+        } else {
+          // no points and no commas => English format
+          numberFormat = NumberFormatInfo.InvariantInfo;
+          separator = POSSIBLE_SEPARATORS
+            .Where(c => OccurrencesOf(charCounts, c) > 10)
+            .OrderBy(c => -OccurrencesOf(charCounts, c))
+            .DefaultIfEmpty(' ')
+            .First();
+        }
+      }
+    }
+
+    private int OccurrencesOf(Dictionary<char, int> charCounts, char c) {
+      return charCounts.ContainsKey(c) ? charCounts[c] : 0;
+    }
+
+    #region tokenizer
+    internal enum TokenTypeEnum {
+      NewLine, Separator, String, Double
+    }
+
+    internal class Token {
+      public TokenTypeEnum type;
+      public string stringValue;
+      public double doubleValue;
+
+      public Token(TokenTypeEnum type, string value) {
+        this.type = type;
+        stringValue = value;
+        doubleValue = 0.0;
+      }
+
+      public override string ToString() {
+        return stringValue;
+      }
+    }
+
+
+    internal class Tokenizer {
+      private StreamReader reader;
+      private List<Token> tokens;
+      private NumberFormatInfo numberFormatInfo;
+      private char separator;
+      private const string INTERNAL_SEPARATOR = "#";
+
+      private int currentLineNumber = 0;
+      public int CurrentLineNumber {
+        get { return currentLineNumber; }
+        private set { currentLineNumber = value; }
+      }
+      private string currentLine;
+      public string CurrentLine {
+        get { return currentLine; }
+        private set { currentLine = value; }
+      }
+
+      private Token newlineToken;
+      public Token NewlineToken {
+        get { return newlineToken; }
+        private set { newlineToken = value; }
+      }
+      private Token separatorToken;
+      public Token SeparatorToken {
+        get { return separatorToken; }
+        private set { separatorToken = value; }
+      }
+
+      public Tokenizer(StreamReader reader, NumberFormatInfo numberFormatInfo, char separator) {
+        this.reader = reader;
+        this.numberFormatInfo = numberFormatInfo;
+        this.separator = separator;
+        separatorToken = new Token(TokenTypeEnum.Separator, INTERNAL_SEPARATOR);
+        newlineToken = new Token(TokenTypeEnum.NewLine, Environment.NewLine);
+        tokens = new List<Token>();
+        ReadNextTokens();
+      }
+
+      private void ReadNextTokens() {
+        if (!reader.EndOfStream) {
+          CurrentLine = reader.ReadLine();
+          var newTokens = from str in Split(CurrentLine)
+                          let trimmedStr = str.Trim()
+                          where !string.IsNullOrEmpty(trimmedStr)
+                          select MakeToken(trimmedStr);
+
+          tokens.AddRange(newTokens);
+          tokens.Add(NewlineToken);
+          CurrentLineNumber++;
+        }
+      }
+
+      private IEnumerable<string> Split(string line) {
+        StringBuilder subStr = new StringBuilder();
+        foreach (char c in line) {
+          if (c == separator) {
+            yield return subStr.ToString();
+            subStr = new StringBuilder();
+            // all separator characters are transformed to the internally used separator character
+            yield return INTERNAL_SEPARATOR;
+          } else {
+            subStr.Append(c);
+          }
+        }
+        yield return subStr.ToString();
+      }
+
+      private Token MakeToken(string strToken) {
+        Token token = new Token(TokenTypeEnum.String, strToken);
+        if (strToken.Equals(INTERNAL_SEPARATOR)) {
+          return SeparatorToken;
+        } else if (double.TryParse(strToken, NumberStyles.Float, numberFormatInfo, out token.doubleValue)) {
+          token.type = TokenTypeEnum.Double;
+          return token;
+        }
+
+        // couldn't parse the token as an int or float number so return a string token
+        return token;
+      }
+
+      public Token Peek() {
+        return tokens[0];
+      }
+
+      public Token Next() {
+        Token next = tokens[0];
+        tokens.RemoveAt(0);
+        if (tokens.Count == 0) {
+          ReadNextTokens();
+        }
+        return next;
+      }
+
+      public bool HasNext() {
+        return tokens.Count > 0 || !reader.EndOfStream;
+      }
+    }
+    #endregion
+
+    #region parsing
+    private void Parse() {
+      ParseVariableNames();
+      if (!tokenizer.HasNext()) Error("Couldn't parse data values. Probably because of incorrect number format (the parser expects english number format with a '.' as decimal separator).", "", tokenizer.CurrentLineNumber);
+      ParseValues();
+      if (rowValues.Count == 0) Error("Couldn't parse data values. Probably because of incorrect number format (the parser expects english number format with a '.' as decimal separator).", "", tokenizer.CurrentLineNumber);
+    }
+
+    private void ParseValues() {
+      while (tokenizer.HasNext()) {
+        List<double> row = new List<double>();
+        row.Add(NextValue(tokenizer));
+        while (tokenizer.HasNext() && tokenizer.Peek() == tokenizer.SeparatorToken) {
+          Expect(tokenizer.SeparatorToken);
+          row.Add(NextValue(tokenizer));
+        }
+        Expect(tokenizer.NewlineToken);
+        // all rows have to have the same number of values            
+        // the first row defines how many samples are needed
+        if (rowValues.Count > 0 && rowValues[0].Count != row.Count) {
+          Error("The first row of the dataset has " + rowValues[0].Count + " columns." +
+            "\nLine " + tokenizer.CurrentLineNumber + " has " + row.Count + " columns.", "", tokenizer.CurrentLineNumber);
+        }
+        // add the current row to the collection of rows and start a new row
+        rowValues.Add(row);
+        row = new List<double>();
+      }
+    }
+
+    private double NextValue(Tokenizer tokenizer) {
+      if (tokenizer.Peek() == tokenizer.SeparatorToken || tokenizer.Peek() == tokenizer.NewlineToken) return double.NaN;
+      Token current = tokenizer.Next();
+      if (current.type == TokenTypeEnum.Separator || current.type == TokenTypeEnum.String) {
+        return double.NaN;
+      } else if (current.type == TokenTypeEnum.Double) {
+        // just take the value
+        return current.doubleValue;
+      }
+      // found an unexpected token => throw error 
+      Error("Unexpected token.", current.stringValue, tokenizer.CurrentLineNumber);
+      // this line is never executed because Error() throws an exception
+      throw new InvalidOperationException();
+    }
+
+    private void ParseVariableNames() {
+      // if the first line doesn't start with a double value then we assume that the
+      // first line contains variable names
+      if (tokenizer.HasNext() && tokenizer.Peek().type != TokenTypeEnum.Double) {
+
+        List<Token> tokens = new List<Token>();
+        Token valueToken;
+        valueToken = tokenizer.Next();
+        tokens.Add(valueToken);
+        while (tokenizer.HasNext() && tokenizer.Peek() == tokenizer.SeparatorToken) {
+          Expect(tokenizer.SeparatorToken);
+          valueToken = tokenizer.Next();
+          if (valueToken != tokenizer.NewlineToken) {
+            tokens.Add(valueToken);
+          }
+        }
+        if (valueToken != tokenizer.NewlineToken) {
+          Expect(tokenizer.NewlineToken);
+        }
+        variableNames = tokens.Select(x => x.stringValue.Trim()).ToList();
+      }
+    }
+
+    private void Expect(Token expectedToken) {
+      Token actualToken = tokenizer.Next();
+      if (actualToken != expectedToken) {
+        Error("Expected: " + expectedToken, actualToken.stringValue, tokenizer.CurrentLineNumber);
+      }
+    }
+
+    private void Error(string message, string token, int lineNumber) {
+      throw new DataFormatException("Error while parsing.\n" + message, token, lineNumber);
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/HeuristicLab.Problems.DataAnalysis.Tests-3.3.csproj
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/HeuristicLab.Problems.DataAnalysis.Tests-3.3.csproj	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/HeuristicLab.Problems.DataAnalysis.Tests-3.3.csproj	(revision 5275)
@@ -102,4 +102,31 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="ALGLIB-3.1.0">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\ALGLIB-3.1.0.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.ALGLIB-3.1.0">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.ALGLIB-3.1.0.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3">
+      <HintPath>..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
     <Reference Include="System" />
Index: branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/StatisticCalculatorsTest.cs
===================================================================
--- branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/StatisticCalculatorsTest.cs	(revision 5265)
+++ branches/DataAnalysis/HeuristicLab.Problems.DataAnalysis/3.3/Tests/StatisticCalculatorsTest.cs	(revision 5275)
@@ -77,5 +77,5 @@
           double tmp = 0;
 
-          alglib.descriptivestatistics.calculatemoments(ref xs, n, ref mean_alglib, ref variance_alglib, ref tmp, ref tmp);
+          alglib.basestat.samplemoments(xs, n, ref mean_alglib, ref variance_alglib, ref tmp, ref tmp);
 
           var calculator = new OnlineMeanAndVarianceCalculator();
@@ -108,5 +108,5 @@
             double[] xs = x.ToArray();
             double[] ys = y.ToArray();
-            double r2_alglib = alglib.correlation.pearsoncorrelation(ref xs, ref ys, n);
+            double r2_alglib = alglib.pearsoncorr2(xs, ys, n);
             r2_alglib *= r2_alglib;
 
