Index: /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 258)
+++ /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 259)
@@ -28,4 +28,5 @@
 using HeuristicLab.Data;
 using System.Xml;
+using System.Globalization;
 
 namespace HeuristicLab.Functions {
@@ -33,5 +34,5 @@
     private List<int> code;
     private List<double> data;
-
+    private static BakedTreeEvaluator evaluator = new BakedTreeEvaluator();
     public BakedFunctionTree() {
       code = new List<int>();
@@ -42,5 +43,5 @@
       : this() {
       code.Add(0);
-      code.Add(BakedTreeEvaluator.MapFunction(function));
+      code.Add(evaluator.MapFunction(function));
       code.Add(0);
       treesExpanded = true;
@@ -58,5 +59,5 @@
       : this() {
       code.Add(0);
-      code.Add(BakedTreeEvaluator.MapFunction(tree.Function));
+      code.Add(evaluator.MapFunction(tree.Function));
       code.Add(tree.LocalVariables.Count);
       foreach(IVariable variable in tree.LocalVariables) {
@@ -158,5 +159,5 @@
         if(!variablesExpanded) {
           variables = new List<IVariable>();
-          IFunction function = BakedTreeEvaluator.MapSymbol(code[1]);
+          IFunction function = evaluator.MapSymbol(code[1]);
           int localVariableIndex = 0;
           foreach(IVariableInfo variableInfo in function.VariableInfos) {
@@ -186,5 +187,5 @@
 
     public IFunction Function {
-      get { return BakedTreeEvaluator.MapSymbol(code[1]); }
+      get { return evaluator.MapSymbol(code[1]); }
     }
 
@@ -220,9 +221,8 @@
     }
 
-    private BakedTreeEvaluator evaluator;
     public double Evaluate(Dataset dataset, int sampleIndex) {
       FlattenVariables();
       FlattenTrees();
-      if(evaluator == null) evaluator = new BakedTreeEvaluator(code, data);
+      evaluator.SetCode(code, data);
       return evaluator.Evaluate(dataset, sampleIndex);
     }
@@ -230,14 +230,17 @@
 
     public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      FlattenVariables();
+      FlattenTrees();
       XmlNode node = base.GetXmlNode(name, document, persistedObjects);
-      node.AppendChild(PersistenceManager.Persist("Function", Function, document, persistedObjects));
-      XmlNode subTreesNode = document.CreateNode(XmlNodeType.Element, "SubTrees", null);
-      for(int i = 0; i < SubTrees.Count; i++)
-        subTreesNode.AppendChild(PersistenceManager.Persist(SubTrees[i], document, persistedObjects));
-      node.AppendChild(subTreesNode);
-      XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "Variables", null);
-      foreach(IVariable variable in LocalVariables)
-        variablesNode.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
-      node.AppendChild(variablesNode);
+      if(evaluator != null) {
+        XmlNode evaluatorNode = PersistenceManager.Persist("Evaluator", evaluator, document, persistedObjects);
+        node.AppendChild(evaluatorNode);
+      }
+      XmlAttribute codeAttribute = document.CreateAttribute("Code");
+      codeAttribute.Value = GetString<int>(code);
+      node.Attributes.Append(codeAttribute);
+      XmlAttribute dataAttribute = document.CreateAttribute("Data");
+      dataAttribute.Value = GetString<double>(data);
+      node.Attributes.Append(dataAttribute);
       return node;
     }
@@ -245,18 +248,30 @@
     public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
       base.Populate(node, restoredObjects);
-      IFunction function = (IFunction)PersistenceManager.Restore(node.SelectSingleNode("Function"), restoredObjects);
-      code.Add(0);
-      code.Add(BakedTreeEvaluator.MapFunction(function));
-      code.Add(0);
-      treesExpanded = true;
-      subTrees = new List<IFunctionTree>();
-      variables = new List<IVariable>();
-      variablesExpanded = true;
-      XmlNode subTreesNode = node.SelectSingleNode("SubTrees");
-      for(int i = 0; i < subTreesNode.ChildNodes.Count; i++)
-        subTrees.Add((IFunctionTree)PersistenceManager.Restore(subTreesNode.ChildNodes[i], restoredObjects));
-      XmlNode variablesNode = node.SelectSingleNode("Variables");
-      foreach(XmlNode variableNode in variablesNode.ChildNodes)
-        variables.Add((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
+      XmlNode evaluatorNode = node.SelectSingleNode("Evaluator");
+      if(evaluatorNode != null) {
+        BakedTreeEvaluator evaluator = (BakedTreeEvaluator)PersistenceManager.Restore(evaluatorNode, restoredObjects);
+        BakedFunctionTree.evaluator = evaluator;
+      }
+      code = GetList<int>(node.Attributes["Code"].Value, s => int.Parse(s, CultureInfo.InvariantCulture));
+      data = GetList<double>(node.Attributes["Data"].Value, s => double.Parse(s, CultureInfo.InvariantCulture));
+    }
+
+    private string GetString<T>(IEnumerable<T> xs) where T : IConvertible {
+      StringBuilder builder = new StringBuilder();
+      foreach(T x in xs) {
+        builder.Append(x.ToString(CultureInfo.InvariantCulture) + "; ");
+      }
+      if(builder.Length > 0) builder.Remove(builder.Length - 2, 2);
+      return builder.ToString();
+    }
+
+    private List<T> GetList<T>(string s, Converter<string, T> converter) {
+      List<T> result = new List<T>();
+      string[] tokens = s.Split(new char[] {';',' '}, StringSplitOptions.RemoveEmptyEntries);
+      foreach(string token in tokens) {
+        T x = converter(token.Trim());
+        result.Add(x);
+      }
+      return result;
     }
 
@@ -264,5 +279,5 @@
       BakedFunctionTree clone = new BakedFunctionTree();
       // in case the user (de)serialized the tree between evaluation and selection we have to flatten the tree again.
-      if(treesExpanded) FlattenTrees(); 
+      if(treesExpanded) FlattenTrees();
       if(variablesExpanded) FlattenVariables();
       clone.code.AddRange(code);
Index: /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs	(revision 258)
+++ /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs	(revision 259)
@@ -4,7 +4,9 @@
 using System.Text;
 using HeuristicLab.DataAnalysis;
+using HeuristicLab.Core;
+using System.Xml;
 
 namespace HeuristicLab.Functions {
-  internal class BakedTreeEvaluator {
+  internal class BakedTreeEvaluator : StorableBase {
     private const int ADDITION = 10010;
     private const int AND = 10020;
@@ -31,14 +33,14 @@
     private const int XOR = 10230;
 
-    private static int nextFunctionSymbol = 10240;
-    private static Dictionary<int, IFunction> symbolTable;
-    private static Dictionary<IFunction, int> reverseSymbolTable;
-    private static Dictionary<Type, int> staticTypes;
-    private static int MAX_CODE_LENGTH = 4096;
-    private static int MAX_DATA_LENGTH = 4096;
-    private static int[] codeArr = new int[MAX_CODE_LENGTH];
-    private static double[] dataArr = new double[MAX_DATA_LENGTH];
-
-    static BakedTreeEvaluator() {
+    private int nextFunctionSymbol = 10240;
+    private Dictionary<int, IFunction> symbolTable;
+    private Dictionary<IFunction, int> reverseSymbolTable;
+    private Dictionary<Type, int> staticTypes;
+    private const int MAX_CODE_LENGTH = 4096;
+    private const int MAX_DATA_LENGTH = 4096;
+    private int[] codeArr = new int[MAX_CODE_LENGTH];
+    private double[] dataArr = new double[MAX_DATA_LENGTH];
+
+    public BakedTreeEvaluator() {
       symbolTable = new Dictionary<int, IFunction>();
       reverseSymbolTable = new Dictionary<IFunction, int>();
@@ -69,10 +71,5 @@
     }
 
-    internal BakedTreeEvaluator(List<int> code, List<double> data) {
-      code.CopyTo(codeArr);
-      data.CopyTo(dataArr);
-    }
-
-    internal static int MapFunction(IFunction function) {
+    internal int MapFunction(IFunction function) {
       if(!reverseSymbolTable.ContainsKey(function)) {
         int curFunctionSymbol;
@@ -88,8 +85,12 @@
     }
 
-    internal static IFunction MapSymbol(int symbol) {
+    internal IFunction MapSymbol(int symbol) {
       return symbolTable[symbol];
     }
 
+    internal void SetCode(List<int> code, List<double> data) {
+      code.CopyTo(codeArr);
+      data.CopyTo(dataArr);
+    }
 
     private int PC;
@@ -108,12 +109,12 @@
     private double EvaluateBakedCode() {
       int arity = codeArr[PC];
-      int functionSymbol = codeArr[PC+1];
-      int nLocalVariables = codeArr[PC+2];
+      int functionSymbol = codeArr[PC + 1];
+      int nLocalVariables = codeArr[PC + 2];
       PC += 3;
       switch(functionSymbol) {
         case VARIABLE: {
             int var = (int)dataArr[DP];
-            double weight = dataArr[DP+1];
-            int row = sampleIndex + (int)dataArr[DP+2];
+            double weight = dataArr[DP + 1];
+            int row = sampleIndex + (int)dataArr[DP + 2];
             DP += 3;
             if(row < 0 || row >= dataset.Rows) return double.NaN;
@@ -202,5 +203,5 @@
             for(int i = 0; i < arity; i++) {
               double x = Math.Round(EvaluateBakedCode());
-              if(x == 0 || x==1.0) result *= x;
+              if(x == 0 || x == 1.0) result *= x;
               else result = double.NaN;
             }
@@ -269,4 +270,39 @@
       }
     }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      throw new NotImplementedException();
+    }
+
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      XmlAttribute nextFunctionSymbolAttribute = document.CreateAttribute("NextFunctionSymbol");
+      nextFunctionSymbolAttribute.Value = nextFunctionSymbol.ToString();
+      node.Attributes.Append(nextFunctionSymbolAttribute);
+      XmlNode symbolTableNode = document.CreateNode(XmlNodeType.Element, "SymbolTable", null);
+      foreach(KeyValuePair<int, IFunction> entry in symbolTable) {
+        XmlNode entryNode = PersistenceManager.Persist("Entry", entry.Value, document, persistedObjects);
+        XmlAttribute symbolAttr = document.CreateAttribute("Symbol");
+        symbolAttr.Value = entry.Key.ToString();
+        entryNode.Attributes.Append(symbolAttr);
+        symbolTableNode.AppendChild(entryNode);
+      }
+      node.AppendChild(symbolTableNode);
+      return node;
+    }
+
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      symbolTable.Clear();
+      reverseSymbolTable.Clear();
+      nextFunctionSymbol = int.Parse(node.Attributes["NextFunctionSymbol"].Value);
+      XmlNode symbolTableNode = node.SelectSingleNode("SymbolTable");
+      foreach(XmlNode entry in symbolTableNode.ChildNodes) {
+        IFunction function = (IFunction)PersistenceManager.Restore(entry, restoredObjects);
+        int symbol = int.Parse(entry.Attributes["Symbol"].Value);
+        symbolTable[symbol] = function;
+        reverseSymbolTable[function] = symbol;
+      }
+    }
   }
 }
