Index: /trunk/sources/HeuristicLab.Functions/Addition.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Addition.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Addition.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Addition : FunctionBase {
+  public sealed class Addition : FunctionBase {
     public override string Description {
       get {
@@ -46,15 +46,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      // (+ 3) => 3
-      // (+ 2 3) => 5
-      // (+ 3 4 5) => 12
-      double sum = 0.0;
-      for (int i = 0; i < args.Length; i++) {
-        sum += args[i];
-      }
-      return sum;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/And.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/And.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/And.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class And : FunctionBase {
+  public sealed class And : FunctionBase {
     public override string Description {
       get {
@@ -42,38 +42,7 @@
     }
 
-    public override IFunctionTree GetTreeNode() {
-      return new AndFunctionTree(this);
-    }
-
-    // special form
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      throw new NotImplementedException();
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
   }
-
-  class AndFunctionTree : FunctionTree {
-    public AndFunctionTree() : base() { }
-    public AndFunctionTree(And and) : base(and) { }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      foreach(IFunctionTree subTree in SubTrees) {
-        double result = Math.Round(subTree.Evaluate(dataset, sampleIndex));
-        if(result == 0.0) return 0.0; // one sub-tree is 0.0 (false) => return false
-        else if(result != 1.0) return double.NaN;
-      }
-      // all sub-trees evaluated to 1.0 (true) => return 1.0 (true)
-      return 1.0;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      AndFunctionTree clone = new AndFunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      return clone;
-    }
-  }
 }
Index: /trunk/sources/HeuristicLab.Functions/Average.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Average.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Average.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Average : FunctionBase {
+  public sealed class Average : FunctionBase {
     public override string Description {
       get {
@@ -40,12 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      double sum = 0.0;
-      for(int i = 0; i < args.Length; i++) {
-        sum += args[i];
-      }
-      return sum / args.Length;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 229)
+++ /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 229)
@@ -0,0 +1,275 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Linq;
+using System.Text;
+using HeuristicLab.Core;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Data;
+using System.Xml;
+
+namespace HeuristicLab.Functions {
+  class BakedFunctionTree : ItemBase, IFunctionTree {
+    private List<int> code;
+    private List<double> data;
+
+    public BakedFunctionTree() {
+      code = new List<int>();
+      data = new List<double>();
+    }
+
+    internal BakedFunctionTree(IFunction function)
+      : this() {
+      code.Add(0);
+      code.Add(BakedTreeEvaluator.MapFunction(function));
+      code.Add(0);
+      treesExpanded = true;
+      subTrees = new List<IFunctionTree>();
+      variables = new List<IVariable>();
+      variablesExpanded = true;
+      foreach(IVariableInfo variableInfo in function.VariableInfos) {
+        if(variableInfo.Local) {
+          variables.Add((IVariable)function.GetVariable(variableInfo.FormalName).Clone());
+        }
+      }
+    }
+
+    internal BakedFunctionTree(IFunctionTree tree)
+      : this() {
+      code.Add(0);
+      code.Add(BakedTreeEvaluator.MapFunction(tree.Function));
+      code.Add(tree.LocalVariables.Count);
+      foreach(IVariable variable in tree.LocalVariables) {
+        IItem value = variable.Value;
+        data.Add(GetDoubleValue(value));
+      }
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        AddSubTree(new BakedFunctionTree(subTree));
+      }
+    }
+
+    private double GetDoubleValue(IItem value) {
+      if(value is DoubleData) {
+        return ((DoubleData)value).Data;
+      } else if(value is ConstrainedDoubleData) {
+        return ((ConstrainedDoubleData)value).Data;
+      } else if(value is IntData) {
+        return ((IntData)value).Data;
+      } else if(value is ConstrainedIntData) {
+        return ((ConstrainedIntData)value).Data;
+      } else throw new NotSupportedException("Invalid datatype of local variable for GP");
+    }
+
+    private void BranchLength(int branchRoot, out int codeLength, out int dataLength) {
+      int arity = code[branchRoot];
+      int nLocalVariables = code[branchRoot + 2];
+      codeLength = 3;
+      dataLength = nLocalVariables;
+      int subBranchStart = branchRoot + codeLength;
+      for(int i = 0; i < arity; i++) {
+        int branchCodeLength;
+        int branchDataLength;
+        BranchLength(subBranchStart, out branchCodeLength, out branchDataLength);
+        subBranchStart += branchCodeLength;
+        codeLength += branchCodeLength;
+        dataLength += branchDataLength;
+      }
+    }
+
+    private void FlattenTrees() {
+      if(treesExpanded) {
+        code[0] = subTrees.Count;
+        foreach(BakedFunctionTree subTree in subTrees) {
+          subTree.FlattenVariables();
+          subTree.FlattenTrees();
+          code.AddRange(subTree.code);
+          data.AddRange(subTree.data);
+        }
+        treesExpanded = false;
+        subTrees = null;
+      }
+    }
+
+    private void FlattenVariables() {
+      if(variablesExpanded) {
+        code[2] = variables.Count;
+        foreach(IVariable variable in variables) {
+          data.Add(GetDoubleValue(variable.Value));
+        }
+        variablesExpanded = false;
+        variables = null;
+      }
+    }
+
+    private bool treesExpanded = false;
+    private List<IFunctionTree> subTrees;
+    public IList<IFunctionTree> SubTrees {
+      get {
+        if(!treesExpanded) {
+          subTrees = new List<IFunctionTree>();
+          int arity = code[0];
+          int nLocalVariables = code[2];
+          int branchIndex = 3;
+          int dataIndex = nLocalVariables; // skip my local variables to reach the local variables of the first branch
+          for(int i = 0; i < arity; i++) {
+            BakedFunctionTree subTree = new BakedFunctionTree();
+            int codeLength;
+            int dataLength;
+            BranchLength(branchIndex, out codeLength, out dataLength);
+            subTree.code = code.GetRange(branchIndex, codeLength);
+            subTree.data = data.GetRange(dataIndex, dataLength);
+            branchIndex += codeLength;
+            dataIndex += dataLength;
+            subTrees.Add(subTree);
+          }
+          treesExpanded = true;
+          code.RemoveRange(3, code.Count - 3);
+          code[0] = 0;
+          data.RemoveRange(nLocalVariables, data.Count - nLocalVariables);
+        }
+        return subTrees;
+      }
+    }
+
+    private bool variablesExpanded = false;
+    private List<IVariable> variables;
+    public ICollection<IVariable> LocalVariables {
+      get {
+        if(!variablesExpanded) {
+          variables = new List<IVariable>();
+          IFunction function = BakedTreeEvaluator.MapSymbol(code[1]);
+          int localVariableIndex = 0;
+          foreach(IVariableInfo variableInfo in function.VariableInfos) {
+            if(variableInfo.Local) {
+              IVariable clone = (IVariable)function.GetVariable(variableInfo.FormalName).Clone();
+              IItem value = clone.Value;
+              if(value is ConstrainedDoubleData) {
+                ((ConstrainedDoubleData)value).Data = data[localVariableIndex];
+              } else if(value is ConstrainedIntData) {
+                ((ConstrainedIntData)value).Data = (int)data[localVariableIndex];
+              } else if(value is DoubleData) {
+                ((DoubleData)value).Data = data[localVariableIndex];
+              } else if(value is IntData) {
+                ((IntData)value).Data = (int)data[localVariableIndex];
+              } else throw new NotSupportedException("Invalid local variable type for GP.");
+              variables.Add(clone);
+              localVariableIndex++;
+            }
+          }
+          variablesExpanded = true;
+          code[2] = 0;
+          data.RemoveRange(0, variables.Count);
+        }
+        return variables;
+      }
+    }
+
+    public IFunction Function {
+      get { return BakedTreeEvaluator.MapSymbol(code[1]); }
+    }
+
+    public IVariable GetLocalVariable(string name) {
+      foreach(IVariable var in LocalVariables) {
+        if(var.Name == name) return var;
+      }
+      return null;
+    }
+
+    public void AddVariable(IVariable variable) {
+      throw new NotSupportedException();
+    }
+
+    public void RemoveVariable(string name) {
+      throw new NotSupportedException();
+    }
+
+    public void AddSubTree(IFunctionTree tree) {
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.Add(tree);
+    }
+
+    public void InsertSubTree(int index, IFunctionTree tree) {
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.Insert(index, tree);
+    }
+
+    public void RemoveSubTree(int index) {
+      // sanity check
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.RemoveAt(index);
+    }
+
+    public double Evaluate(Dataset dataset, int sampleIndex) {
+      FlattenVariables();
+      FlattenTrees();
+      return BakedTreeEvaluator.Evaluate(dataset, sampleIndex, code, data);
+    }
+
+
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      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);
+      return node;
+    }
+
+    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));
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      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(variablesExpanded) FlattenVariables();
+      clone.code.AddRange(code);
+      clone.data.AddRange(data);
+      return clone;
+    }
+
+    public override IView CreateView() {
+      return new FunctionTreeView(this);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs	(revision 229)
+++ /trunk/sources/HeuristicLab.Functions/BakedTreeEvaluator.cs	(revision 229)
@@ -0,0 +1,276 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.Functions {
+  static class BakedTreeEvaluator {
+    private const int ADDITION = 10010;
+    private const int AND = 10020;
+    private const int AVERAGE = 10030;
+    private const int CONSTANT = 10040;
+    private const int COSINUS = 10050;
+    private const int DIVISION = 10060;
+    private const int EQU = 10070;
+    private const int EXP = 10080;
+    private const int GT = 10090;
+    private const int IFTE = 10100;
+    private const int LT = 10110;
+    private const int LOG = 10120;
+    private const int MULTIPLICATION = 10130;
+    private const int NOT = 10140;
+    private const int OR = 10150;
+    private const int POWER = 10160;
+    private const int SIGNUM = 10170;
+    private const int SINUS = 10180;
+    private const int SQRT = 10190;
+    private const int SUBSTRACTION = 10200;
+    private const int TANGENS = 10210;
+    private const int VARIABLE = 10220;
+    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;
+
+    static BakedTreeEvaluator() {
+      symbolTable = new Dictionary<int, IFunction>();
+      reverseSymbolTable = new Dictionary<IFunction, int>();
+      staticTypes = new Dictionary<Type, int>();
+      staticTypes[typeof(Addition)] = ADDITION;
+      staticTypes[typeof(And)] = AND;
+      staticTypes[typeof(Average)] = AVERAGE;
+      staticTypes[typeof(Constant)] = CONSTANT;
+      staticTypes[typeof(Cosinus)] = COSINUS;
+      staticTypes[typeof(Division)] = DIVISION;
+      staticTypes[typeof(Equal)] = EQU;
+      staticTypes[typeof(Exponential)] = EXP;
+      staticTypes[typeof(GreaterThan)] = GT;
+      staticTypes[typeof(IfThenElse)] = IFTE;
+      staticTypes[typeof(LessThan)] = LT;
+      staticTypes[typeof(Logarithm)] = LOG;
+      staticTypes[typeof(Multiplication)] = MULTIPLICATION;
+      staticTypes[typeof(Not)] = NOT;
+      staticTypes[typeof(Or)] = OR;
+      staticTypes[typeof(Power)] = POWER;
+      staticTypes[typeof(Signum)] = SIGNUM;
+      staticTypes[typeof(Sinus)] = SINUS;
+      staticTypes[typeof(Sqrt)] = SQRT;
+      staticTypes[typeof(Substraction)] = SUBSTRACTION;
+      staticTypes[typeof(Tangens)] = TANGENS;
+      staticTypes[typeof(Variable)] = VARIABLE;
+      staticTypes[typeof(Xor)] = XOR;
+    }
+
+    internal static int MapFunction(IFunction function) {
+      if(!reverseSymbolTable.ContainsKey(function)) {
+        int curFunctionSymbol;
+        if(staticTypes.ContainsKey(function.GetType())) curFunctionSymbol = staticTypes[function.GetType()];
+        else {
+          curFunctionSymbol = nextFunctionSymbol;
+          nextFunctionSymbol++;
+        }
+        reverseSymbolTable[function] = curFunctionSymbol;
+        symbolTable[curFunctionSymbol] = function;
+      }
+      return reverseSymbolTable[function];
+    }
+
+    internal static IFunction MapSymbol(int symbol) {
+      return symbolTable[symbol];
+    }
+
+
+    private static int PC;
+    private static int DP;
+    private static int[] codeArr;
+    private static double[] dataArr;
+    private static Dataset dataset;
+    private static int sampleIndex;
+
+    internal static double Evaluate(Dataset _dataset, int _sampleIndex, List<int> code, List<double> data) {
+      PC = 0;
+      DP = 0;
+      if(codeArr == null || codeArr.Length!=code.Count) {
+        codeArr = new int[code.Count];
+        dataArr = new double[data.Count];
+        code.CopyTo(codeArr);
+        data.CopyTo(dataArr);
+      }
+      sampleIndex = _sampleIndex;
+      dataset = _dataset;
+      return EvaluateBakedCode();
+    }
+
+    private static double EvaluateBakedCode() {
+      int arity = codeArr[PC++];
+      int functionSymbol = codeArr[PC++];
+      int nLocalVariables = codeArr[PC++];
+      switch(functionSymbol) {
+        case VARIABLE: {
+            int var = (int)dataArr[DP++];
+            double weight = dataArr[DP++];
+            int offset = (int)dataArr[DP++];
+            int row = sampleIndex + offset;
+            if(row < 0 || row >= dataset.Rows) return double.NaN;
+            else return weight * dataset.GetValue(row, var);
+          }
+        case CONSTANT: {
+            double value = dataArr[DP++];
+            return value;
+          }
+        case MULTIPLICATION: {
+            double result = 1.0;
+            for(int i = 0; i < arity; i++) {
+              result *= EvaluateBakedCode();
+            }
+            return result;
+          }
+        case ADDITION: {
+            double sum = 0.0;
+            for(int i = 0; i < arity; i++) {
+              sum += EvaluateBakedCode();
+            }
+            return sum;
+          }
+        case SUBSTRACTION: {
+            if(arity == 1) {
+              return -EvaluateBakedCode();
+            } else {
+              double result = EvaluateBakedCode();
+              for(int i = 1; i < arity; i++) {
+                result -= EvaluateBakedCode();
+              }
+              return result;
+            }
+          }
+        case DIVISION: {
+            if(arity == 1) {
+              double divisor = EvaluateBakedCode();
+              if(divisor == 0) return 0;
+              else return 1.0 / divisor;
+            } else {
+              double result = EvaluateBakedCode();
+              for(int i = 1; i < arity; i++) {
+                double divisor = EvaluateBakedCode();
+                if(divisor == 0) result = 0;
+                else result /= divisor;
+              }
+              return result;
+            }
+          }
+        case AVERAGE: {
+            double sum = 0.0;
+            for(int i = 0; i < arity; i++) {
+              sum += EvaluateBakedCode();
+            }
+            return sum / arity;
+          }
+        case COSINUS: {
+            return Math.Cos(EvaluateBakedCode());
+          }
+        case SINUS: {
+            return Math.Sin(EvaluateBakedCode());
+          }
+        case EXP: {
+            return Math.Exp(EvaluateBakedCode());
+          }
+        case LOG: {
+            return Math.Log(EvaluateBakedCode());
+          }
+        case POWER: {
+            double x = EvaluateBakedCode();
+            double p = EvaluateBakedCode();
+            return Math.Pow(x, p);
+          }
+        case SIGNUM: {
+            // protected signum
+            double value = EvaluateBakedCode();
+            if(value < 0) return -1;
+            if(value > 0) return 1;
+            return 0;
+          }
+        case SQRT: {
+            return Math.Sqrt(EvaluateBakedCode());
+          }
+        case TANGENS: {
+            return Math.Tan(EvaluateBakedCode());
+          }
+        case AND: {
+            double result = 1.0;
+            // have to evaluate all sub-trees, skipping would probably not lead to a big gain because 
+            // we have to iterate over the linear structure anyway
+            for(int i = 0; i < arity; i++) {
+              double x = Math.Round(EvaluateBakedCode());
+              if(x == 0) result *= 0;
+              else if(x == 1.0) result *= 1.0;
+              else result *= double.NaN;
+            }
+            return result;
+          }
+        case EQU: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(x == y) return 1.0; else return 0.0;
+          }
+        case GT: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(x > y) return 1.0;
+            else return 0.0;
+          }
+        case IFTE: {
+            double condition = Math.Round(EvaluateBakedCode());
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(condition < .5) return x;
+            else if(condition >= .5) return y;
+            else return double.NaN;
+          }
+        case LT: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(x < y) return 1.0;
+            else return 0.0;
+          }
+        case NOT: {
+            double result = Math.Round(EvaluateBakedCode());
+            if(result == 0.0) return 1.0;
+            else if(result == 1.0) return 0.0;
+            else return double.NaN;
+          }
+        case OR: {
+            double result = 0.0; // default is false
+            for(int i = 0; i < arity; i++) {
+              double x = Math.Round(EvaluateBakedCode());
+              if(x == 1.0 && result == 0.0) result = 1.0; // found first true (1.0) => set to true
+              else if(x != 0.0) result = double.NaN; // if it was not true it can only be false (0.0) all other cases are undefined => (NaN)
+            }
+            return result;
+          }
+        case XOR: {
+            double x = Math.Round(EvaluateBakedCode());
+            double y = Math.Round(EvaluateBakedCode());
+            if(x == 0.0 && y == 0.0) return 0.0;
+            if(x == 1.0 && y == 0.0) return 1.0;
+            if(x == 0.0 && y == 1.0) return 1.0;
+            if(x == 1.0 && y == 1.0) return 0.0;
+            return double.NaN;
+          }
+        default: {
+            IFunction function = symbolTable[functionSymbol];
+            double[] args = new double[nLocalVariables + arity];
+            for(int i = 0; i < nLocalVariables; i++) {
+              args[i] = dataArr[DP++];
+            }
+            for(int j = 0; j < arity; j++) {
+              args[nLocalVariables + j] = EvaluateBakedCode();
+            }
+            return function.Apply(dataset, sampleIndex, args);
+          }
+      }
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Functions/Constant.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Constant.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Constant.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Constant : FunctionBase {
+  public sealed class Constant : FunctionBase {
     public const string VALUE = "Value";
 
@@ -51,46 +51,7 @@
       AddConstraint(new NumberOfSubOperatorsConstraint(0, 0));
     }
-
-    public override IFunctionTree GetTreeNode() {
-      return new ConstantFunctionTree(this);
-    }
-
-    // can't apply a constant
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      throw new NotSupportedException();
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
   }
-
-  class ConstantFunctionTree : FunctionTree {
-    private ConstrainedDoubleData value;
-    public ConstantFunctionTree() : base() { }
-    public ConstantFunctionTree(Constant constant) : base(constant) {
-      UpdateCachedValues();
-    }
-
-    private void UpdateCachedValues() {
-      value = (ConstrainedDoubleData)GetLocalVariable(Constant.VALUE).Value;
-    }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return value.Data;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      ConstantFunctionTree clone = new ConstantFunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      clone.UpdateCachedValues();
-      return clone;
-    }
-
-    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-      UpdateCachedValues();
-    }
-  }
 }
Index: /trunk/sources/HeuristicLab.Functions/Cosinus.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Cosinus.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Cosinus.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Cosinus : FunctionBase {
+  public sealed class Cosinus : FunctionBase {
     public override string Description {
       get { return "Returns the cosinus of the first sub-tree."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Cos(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Division.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Division.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Division.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Division : FunctionBase {
+  public sealed class Division : FunctionBase {
     private const double EPSILON = 10.0E-20; // if any divisor is < EPSILON return 0
 
@@ -52,24 +52,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      // (/ 3) => 1/3
-      // (/ 2 3) => 2/3
-      // (/ 3 4 5) => 3/20
-
-      if(args.Length == 1) {
-        double divisor = args[0];
-        if(Math.Abs(divisor) < EPSILON) return 0;
-        else return 1.0 / divisor;
-      } else {
-        double result = args[0];
-        for(int i = 1; i < args.Length; i++) {
-          double divisor = args[i];
-          if(Math.Abs(divisor) < EPSILON) return 0.0;
-          result /= divisor;
-        }
-        return result;
-      }
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Equal.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Equal.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Equal.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Equal : FunctionBase {
+  public sealed class Equal : FunctionBase {
     public override string Description {
       get {
@@ -40,9 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      if(args[0] == args[1]) return 1.0;
-      else return 0.0;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Exponential.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Exponential.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Exponential.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Exponential : FunctionBase {
+  public sealed class Exponential : FunctionBase {
     public override string Description {
       get { return "Returns returns exponential of the first sub-tree (power(e, x))."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Exp(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/FunctionBase.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/FunctionBase.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/FunctionBase.cs	(revision 229)
@@ -34,6 +34,8 @@
   /// </summary>
   public abstract class FunctionBase : OperatorBase, IFunction {
-    
-    public abstract double Apply(Dataset dataset, int sampleIndex, double[] args);
+
+    public virtual double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotImplementedException();
+    }
 
     public virtual void Accept(IFunctionVisitor visitor) {
@@ -42,5 +44,5 @@
 
     public virtual IFunctionTree GetTreeNode() {
-      return new FunctionTree(this);
+      return new BakedFunctionTree(this);
     }
 
Index: unk/sources/HeuristicLab.Functions/FunctionTree.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/FunctionTree.cs	(revision 228)
+++ 	(revision )
@@ -1,154 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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.Linq;
-using System.Text;
-using HeuristicLab.Core;
-using HeuristicLab.DataAnalysis;
-using System.Xml;
-
-namespace HeuristicLab.Functions {
-  public class FunctionTree : ItemBase, IFunctionTree {
-
-    private List<IFunctionTree> subTrees;
-    private List<IVariable> localVariables;
-    private IFunction function;
-
-    public FunctionTree()
-      : base() {
-      subTrees = new List<IFunctionTree>();
-      localVariables = new List<IVariable>();
-    }
-
-    internal FunctionTree(IFunction function)
-      : this() {
-      this.function = function;
-      // create and store clones of all local variables of the function
-      foreach(VariableInfo info in function.VariableInfos) {
-        if(info.Local) {
-          AddVariable((IVariable)function.GetVariable(info.FormalName).Clone());
-        }
-      }
-    }
-
-    #region IFunctionTree Members
-
-    public IList<IFunctionTree> SubTrees {
-      get { return subTrees; }
-    }
-
-    public ICollection<IVariable> LocalVariables {
-      get { return localVariables; }
-    }
-
-    public IFunction Function {
-      get { return function; }
-    }
-
-    public IVariable GetLocalVariable(string name) {
-      foreach(IVariable var in localVariables) {
-        if(var.Name == name) return var;
-      }
-      return null;
-    }
-
-    public void AddVariable(IVariable variable) {
-      localVariables.Add(variable);
-    }
-
-    public void RemoveVariable(string name) {
-      localVariables.Remove(GetLocalVariable(name));
-    }
-
-    public void AddSubTree(IFunctionTree tree) {
-      subTrees.Add(tree);
-    }
-
-    public void InsertSubTree(int index, IFunctionTree tree) {
-      subTrees.Insert(index, tree);
-    }
-
-    public void RemoveSubTree(int index) {
-      subTrees.RemoveAt(index);
-    }
-
-    double[] evaluationResults;
-    public virtual double Evaluate(Dataset dataset, int sampleIndex) {
-      // lazy creation of evaluationResults to unburden the GC
-      if(evaluationResults == null) {
-        evaluationResults = new double[SubTrees.Count];
-      }
-      for(int i = 0; i < evaluationResults.Length; i++) {
-        evaluationResults[i] = SubTrees[i].Evaluate(dataset, sampleIndex);
-      }
-      return function.Apply(dataset, sampleIndex, evaluationResults);
-    }
-    #endregion
-
-    public override XmlNode GetXmlNode(string name, System.Xml.XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
-      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);
-      return node;
-    }
-
-    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-      function = (IFunction)PersistenceManager.Restore(node.SelectSingleNode("Function"), restoredObjects);
-      XmlNode subTreesNode = node.SelectSingleNode("SubTrees");
-      for(int i = 0; i < subTreesNode.ChildNodes.Count; i++)
-        AddSubTree((IFunctionTree)PersistenceManager.Restore(subTreesNode.ChildNodes[i], restoredObjects));
-      XmlNode variablesNode = node.SelectSingleNode("Variables");
-      foreach(XmlNode variableNode in variablesNode.ChildNodes)
-        AddVariable((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      FunctionTree clone = new FunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      return clone;
-    }
-
-    public void FillClone(FunctionTree clone, IDictionary<Guid, object> clonedObjects) {
-      clone.function = function;
-      foreach(IVariable variable in localVariables) {
-        clone.AddVariable((IVariable)variable.Clone(clonedObjects));
-      }
-      foreach(IFunctionTree tree in subTrees) {
-        clone.AddSubTree((IFunctionTree)tree.Clone(clonedObjects));
-      }
-    }
-
-    public override IView CreateView() {
-      return new FunctionTreeView(this);
-    }
-  }
-}
Index: /trunk/sources/HeuristicLab.Functions/GreaterThan.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/GreaterThan.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/GreaterThan.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class GreaterThan : FunctionBase {
+  public sealed class GreaterThan : FunctionBase {
     public override string Description {
       get {
@@ -39,10 +39,4 @@
       AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
     }
-
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      if(args[0] > args[1]) return 1.0;
-      else return 0.0;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj	(revision 229)
@@ -49,11 +49,20 @@
   <ItemGroup>
     <Compile Include="Addition.cs" />
-    <Compile Include="And.cs" />
+    <Compile Include="And.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="Average.cs" />
+    <Compile Include="BakedFunctionTree.cs" />
+    <Compile Include="BakedTreeEvaluator.cs" />
     <Compile Include="Constant.cs" />
     <Compile Include="GreaterThan.cs" />
-    <Compile Include="FunctionTree.cs" />
+    <Compile Include="IfThenElse.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="IFunctionTree.cs" />
     <Compile Include="ModelAnalyzerExporter.cs" />
+    <Compile Include="Or.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="ProgrammableFunction.cs" />
     <Compile Include="Equal.cs" />
@@ -64,9 +73,7 @@
       <DependentUpon>FunctionView.cs</DependentUpon>
     </Compile>
-    <Compile Include="IfThenElse.cs" />
     <Compile Include="IFunctionVisitor.cs" />
     <Compile Include="LessThan.cs" />
     <Compile Include="Not.cs" />
-    <Compile Include="Or.cs" />
     <Compile Include="Signum.cs" />
     <Compile Include="Logarithm.cs" />
Index: /trunk/sources/HeuristicLab.Functions/IfThenElse.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/IfThenElse.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/IfThenElse.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class IfThenElse : FunctionBase {
+  public sealed class IfThenElse : FunctionBase {
     public override string Description {
       get {
@@ -41,35 +41,7 @@
     }
 
-    public override IFunctionTree GetTreeNode() {
-      return new IfThenElseFunctionTree(this);
-    }
-
-    // special form
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      throw new NotImplementedException();
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
   }
-
-  class IfThenElseFunctionTree : FunctionTree {
-    public IfThenElseFunctionTree() : base() { }
-    public IfThenElseFunctionTree(IfThenElse ifte) : base(ifte) { }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      double condition = Math.Round(SubTrees[0].Evaluate(dataset, sampleIndex));
-      if(condition < .5) return SubTrees[1].Evaluate(dataset, sampleIndex);
-      else if(condition >= .5) return SubTrees[2].Evaluate(dataset, sampleIndex);
-      else return double.NaN;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      IfThenElseFunctionTree clone = new IfThenElseFunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      return clone;
-    }
-  }
 }
Index: /trunk/sources/HeuristicLab.Functions/LessThan.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/LessThan.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/LessThan.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class LessThan : FunctionBase {
+  public sealed class LessThan : FunctionBase {
     public override string Description {
       get {
@@ -40,9 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      if(args[0] < args[1]) return 1.0;
-      else return 0.0;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Logarithm.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Logarithm.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Logarithm.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Logarithm : FunctionBase {
+  public sealed class Logarithm : FunctionBase {
     public override string Description {
       get { return "Returns the natural (base e) logarithm of the first sub-tree."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Log(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Multiplication.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Multiplication.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Multiplication.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Multiplication : FunctionBase {
+  public sealed class Multiplication : FunctionBase {
     public override string Description {
       get {
@@ -46,15 +46,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      // (* 3) => 3
-      // (* 2 3) => 6
-      // (* 3 4 5) => 60
-      double result = 1.0;
-      for(int i = 0; i < args.Length; i++) {
-        result *= args[i];
-      }
-      return result;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Not.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Not.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Not.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Not : FunctionBase {
+  public sealed class Not : FunctionBase {
     public override string Description {
       get {
@@ -40,11 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      double result = Math.Round(args[0]);
-      if(result == 0.0) return 1.0;
-      else if(result == 1.0) return 0.0;
-      else return double.NaN;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Or.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Or.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Or.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Or : FunctionBase {
+  public sealed class Or : FunctionBase {
     public override string Description {
       get {
@@ -41,36 +41,7 @@
     }
 
-    public override IFunctionTree GetTreeNode() {
-      return new OrFunctionTree(this);
-    }
-    // or is a special form and can't be applied
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      throw new NotImplementedException();
-    }
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
   }
-
-  class OrFunctionTree : FunctionTree {
-    public OrFunctionTree() : base() { }
-    public OrFunctionTree(Or or) : base(or) { }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      foreach(IFunctionTree subTree in SubTrees) {
-        double result = Math.Round(subTree.Evaluate(dataset, sampleIndex));
-        if(result == 1.0) return 1.0; // sub-tree evaluates to 1.0 (true) return 1.0
-        else if(result != 0.0) return double.NaN;
-      }
-      // all sub-trees evaluated to 0.0 (false) return false
-      return 0.0;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      OrFunctionTree clone = new OrFunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      return clone;
-    }
-  }
 }
Index: /trunk/sources/HeuristicLab.Functions/Power.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Power.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Power.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Power : FunctionBase {
+  public sealed class Power : FunctionBase {
     public override string Description {
       get { return "Returns the result of the first sub-tree to the power of the second sub-tree (power(x, y))."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Pow(args[0], args[1]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs	(revision 229)
@@ -36,5 +36,5 @@
 
 namespace HeuristicLab.Functions {
-  public class ProgrammableFunction : ProgrammableOperator, IFunction {
+  public sealed class ProgrammableFunction : ProgrammableOperator, IFunction {
     private MethodInfo applyMethod;
     public ProgrammableFunction()
@@ -120,5 +120,5 @@
 
     public IFunctionTree GetTreeNode() {
-      return new ProgrammableFunctionTree(this);
+      return new BakedFunctionTree(this);
     }
 
@@ -187,30 +187,30 @@
   }
 
-  class ProgrammableFunctionTree : FunctionTree {
-    private ProgrammableFunction progFun;
-    public ProgrammableFunctionTree() : base() { }
-    public ProgrammableFunctionTree(ProgrammableFunction progFun) : base(progFun) {
-      this.progFun = progFun;
-    }
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      // evaluate sub-trees
-      double[] evaluationResults = new double[SubTrees.Count];
-      for(int subTree = 0; subTree < SubTrees.Count; subTree++) {
-        evaluationResults[subTree] = SubTrees[subTree].Evaluate(dataset, sampleIndex);
-      }
-
-      // collect parameters
-      object[] parameters = new object[LocalVariables.Count + 3];
-      parameters[0] = dataset;
-      parameters[1] = sampleIndex;
-      int i = 2;
-      // all local variables are available in the custom function
-      foreach(IVariable variable in LocalVariables) {
-        parameters[i] = variable;
-        i++;
-      }
-      parameters[i] = evaluationResults;
-      return progFun.Call(parameters);
-    }
-  }
+  //class ProgrammableFunctionTree : FunctionTree {
+  //  private ProgrammableFunction progFun;
+  //  public ProgrammableFunctionTree() : base() { }
+  //  public ProgrammableFunctionTree(ProgrammableFunction progFun) : base(progFun) {
+  //    this.progFun = progFun;
+  //  }
+  //  public override double Evaluate(Dataset dataset, int sampleIndex) {
+  //    // evaluate sub-trees
+  //    double[] evaluationResults = new double[SubTrees.Count];
+  //    for(int subTree = 0; subTree < SubTrees.Count; subTree++) {
+  //      evaluationResults[subTree] = SubTrees[subTree].Evaluate(dataset, sampleIndex);
+  //    }
+
+  //    // collect parameters
+  //    object[] parameters = new object[LocalVariables.Count + 3];
+  //    parameters[0] = dataset;
+  //    parameters[1] = sampleIndex;
+  //    int i = 2;
+  //    // all local variables are available in the custom function
+  //    foreach(IVariable variable in LocalVariables) {
+  //      parameters[i] = variable;
+  //      i++;
+  //    }
+  //    parameters[i] = evaluationResults;
+  //    return progFun.Call(parameters);
+  //  }
+  //}
 }
Index: /trunk/sources/HeuristicLab.Functions/Signum.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Signum.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Signum.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Signum : FunctionBase {
+  public sealed class Signum : FunctionBase {
     public override string Description {
       get { return "Returns the signum of the first sub-tree."; }
@@ -40,11 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      double value = args[0];
-      if(value < 0) return -1;
-      if(value > 0) return 1;
-      return 0;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Sinus.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Sinus.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Sinus.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Sinus : FunctionBase {
+  public sealed class Sinus : FunctionBase {
     public override string Description {
       get { return "Returns the sinus of the first sub-tree."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Sin(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Sqrt.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Sqrt.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Sqrt.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Sqrt : FunctionBase {
+  public sealed class Sqrt : FunctionBase {
     public override string Description {
       get { return "Returns the square root of the first sub-tree."; }
@@ -40,9 +40,4 @@
     }
 
-
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Sqrt(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Substraction.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Substraction.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Substraction.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Substraction : FunctionBase {
+  public sealed class Substraction : FunctionBase {
     public override string Description {
       get {
@@ -46,17 +46,4 @@
     }
 
-
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      if(args.Length == 1) {
-        return -args[0];
-      } else {
-        double result = args[0];
-        for(int i = 1; i < args.Length; i++) {
-          result -= args[i];
-        }
-        return result;
-      }
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Tangens.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Tangens.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Tangens.cs	(revision 229)
@@ -29,5 +29,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Tangens : FunctionBase {
+  public sealed class Tangens : FunctionBase {
     public override string Description {
       get { return "Returns the tangens of the first sub-tree."; }
@@ -40,8 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      return Math.Tan(args[0]);
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: /trunk/sources/HeuristicLab.Functions/Variable.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Variable.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Variable.cs	(revision 229)
@@ -30,5 +30,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Variable : FunctionBase {
+  public sealed class Variable : FunctionBase {
 
     public const string WEIGHT = "Weight";
@@ -37,7 +37,9 @@
 
     public override string Description {
-      get { return @"Variable reads a value from a dataset, multiplies that value with a given factor and returns the result.
+      get {
+        return @"Variable reads a value from a dataset, multiplies that value with a given factor and returns the result.
 The variable 'SampleOffset' can be used to read a value from previous or following rows.
-The index of the row that is actually read is SampleIndex+SampleOffset)."; }
+The index of the row that is actually read is SampleIndex+SampleOffset).";
+      }
     }
 
@@ -68,50 +70,7 @@
     }
 
-    public override IFunctionTree GetTreeNode() {
-      return new VariableFunctionTree(this);
-    }
-
-    // can't apply a variable
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      throw new NotSupportedException();
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
   }
-  class VariableFunctionTree : FunctionTree {
-    private ConstrainedDoubleData weight;
-    private ConstrainedIntData index;
-    private ConstrainedIntData offset;
-
-    public VariableFunctionTree() : base() { }
-    public VariableFunctionTree(Variable variable) : base(variable) {
-      UpdateCachedValues();
-    }
-
-    protected void UpdateCachedValues() {
-      weight = (ConstrainedDoubleData)GetLocalVariable(Variable.WEIGHT).Value;
-      index = (ConstrainedIntData)GetLocalVariable(Variable.INDEX).Value;
-      offset = (ConstrainedIntData)GetLocalVariable(Variable.OFFSET).Value;
-    }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      if(sampleIndex + offset.Data < 0 || sampleIndex + offset.Data >= dataset.Rows) return double.NaN;
-      return weight.Data * dataset.GetValue(sampleIndex + offset.Data, index.Data);
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      VariableFunctionTree clone = new VariableFunctionTree();
-      clonedObjects.Add(clone.Guid, clone);
-      FillClone(clone, clonedObjects);
-      clone.UpdateCachedValues();
-      return clone;
-    }
-
-    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-      UpdateCachedValues();
-    }
-  }
 }
Index: /trunk/sources/HeuristicLab.Functions/Xor.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/Xor.cs	(revision 228)
+++ /trunk/sources/HeuristicLab.Functions/Xor.cs	(revision 229)
@@ -28,5 +28,5 @@
 
 namespace HeuristicLab.Functions {
-  public class Xor : FunctionBase {
+  public sealed class Xor : FunctionBase {
     public override string Description {
       get {
@@ -40,10 +40,4 @@
     }
 
-    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
-      if(args[0] == 0.0 && args[1] == 0.0) return 0.0;
-      if(args[0] * args[1] == 0.0) return 1.0;
-      return 0.0;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
