Index: trunk/sources/HeuristicLab.Functions/Addition.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Addition.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Addition.cs	(revision 155)
@@ -33,5 +33,5 @@
     public override string Description {
       get {
-        return @"Returns the sum of all sub-operator results.
+        return @"Returns the sum of all sub-tree results.
     (+ 3) => 3
     (+ 2 3) => 5
@@ -46,24 +46,13 @@
     }
 
-    public Addition(Addition source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
+    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 = SubFunctions.Count - 1; i >= 0; i--) {
-        sum += SubFunctions[i].Evaluate(dataset, sampleIndex);
+      for (int i = 0; i < args.Length; i++) {
+        sum += args[i];
       }
       return sum;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Addition clone = new Addition(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/And.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/And.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/And.cs	(revision 155)
@@ -31,5 +31,7 @@
     public override string Description {
       get {
-        return @"Logical AND operation. Only defined for sub-operator-results 0.0 and 1.0.";
+        return @"Logical AND operation. Only defined for sub-tree-results 0.0 and 1.0.
+AND is a special form, sub-trees are evaluated from the first to the last. Evaluation is 
+stopped as soon as one of the sub-trees evaluates to 0.0 (false).";
       }
     }
@@ -40,22 +42,17 @@
     }
 
-    public And(And source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      foreach(IFunction subFunction in SubFunctions) {
-        double result = Math.Round(subFunction.Evaluate(dataset, sampleIndex));
-        if(result == 0.0) return 0.0;
+    // special form
+    public override double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      foreach(IFunctionTree subTree in tree.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) {
-      And clone = new And(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotImplementedException();
     }
 
Index: trunk/sources/HeuristicLab.Functions/Average.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Average.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Average.cs	(revision 155)
@@ -31,5 +31,5 @@
     public override string Description {
       get {
-        return @"Returns the average (arithmetic mean) of all sub-operator results.";
+        return @"Returns the average (arithmetic mean) of all sub-tree results.";
       }
     }
@@ -40,21 +40,10 @@
     }
 
-    public Average(Average source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
       double sum = 0.0;
-      for(int i = 0; i < SubFunctions.Count; i++) {
-        sum += SubFunctions[i].Evaluate(dataset, sampleIndex);
+      for(int i = 0; i < args.Length; i++) {
+        sum += args[i];
       }
-      return sum / SubFunctions.Count;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Average clone = new Average(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
+      return sum / args.Length;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Constant.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Constant.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Constant.cs	(revision 155)
@@ -31,6 +31,5 @@
 namespace HeuristicLab.Functions {
   public class Constant : FunctionBase {
-
-    private IVariable value;
+    public static readonly string VALUE = "Value";
 
     public override string Description {
@@ -38,22 +37,14 @@
     }
 
-    public ConstrainedDoubleData Value {
-      get {
-        return (ConstrainedDoubleData)value.Value;
-      }
-    }
-
     public Constant()
       : base() {
-      AddVariableInfo(new VariableInfo("Value", "The constant value", typeof(ConstrainedDoubleData), VariableKind.None));
-      GetVariableInfo("Value").Local = true;
+      AddVariableInfo(new VariableInfo(VALUE, "The constant value", typeof(ConstrainedDoubleData), VariableKind.None));
+      GetVariableInfo(VALUE).Local = true;
 
       ConstrainedDoubleData valueData = new ConstrainedDoubleData();
       // initialize a default range for the contant value
       valueData.AddConstraint(new DoubleBoundedConstraint(-20.0, 20.0));
-
-      // create the local variable
-      value = new HeuristicLab.Core.Variable("Value", valueData);
-      AddLocalVariable(value);
+      HeuristicLab.Core.Variable value = new HeuristicLab.Core.Variable(VALUE, valueData);
+      AddVariable(value);
 
       // constant can't have suboperators
@@ -61,24 +52,12 @@
     }
 
-    public Constant(Constant source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-      value = GetVariable("Value");
+    // constant is evaluated directly. Evaluation reads the local variable value from the tree and returns
+    public override double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      return ((ConstrainedDoubleData)tree.GetLocalVariable(VALUE).Value).Data;
     }
 
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Constant clone = new Constant(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
-
-    public override void Populate(XmlNode node, IDictionary<Guid,IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-
-      value = GetVariable("Value");
-    }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return ((ConstrainedDoubleData)value.Value).Data;
+    // can't apply a constant
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotSupportedException();
     }
 
Index: trunk/sources/HeuristicLab.Functions/Cosinus.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Cosinus.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Cosinus.cs	(revision 155)
@@ -31,28 +31,16 @@
   public class Cosinus : FunctionBase {
     public override string Description {
-      get { return "Returns the cosinus of the first sub-operator."; }
+      get { return "Returns the cosinus of the first sub-tree."; }
     }
 
     public Cosinus()
       : base() {
-
       // must have exactly one subfunction
       AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
     }
 
-    public Cosinus(Cosinus source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Cos(args[0]);
     }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Cos(SubFunctions[0].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Cosinus clone = new Cosinus(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/Division.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Division.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Division.cs	(revision 155)
@@ -36,5 +36,5 @@
       get {
         return @"Protected division
-Divides the result of the first sub-operator by the results of the following sub-operators.
+Divides the result of the first sub-tree by the results of the following sub-tree.
 In case one of the divisors is 0 returns 0.
     (/ 3) => 1/3
@@ -48,26 +48,21 @@
     public Division()
       : base() {
-
       // 2 - 3 seems like an reasonable defaut (used for +,-,*,/) (discussion with swinkler and maffenze)
       AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
     }
 
-    public Division(Division source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
       // (/ 3) => 1/3
       // (/ 2 3) => 2/3
       // (/ 3 4 5) => 3/20
 
-      if(SubFunctions.Count == 1) {
-        double divisor = SubFunctions[0].Evaluate(dataset, sampleIndex);
+      if(args.Length == 1) {
+        double divisor = args[0];
         if(Math.Abs(divisor) < EPSILON) return 0;
         else return 1.0 / divisor;
       } else {
-        double result = SubFunctions[0].Evaluate(dataset, sampleIndex);
-        for(int i = 1; i < SubFunctions.Count; i++) {
-          double divisor = SubFunctions[i].Evaluate(dataset, sampleIndex);
+        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;
@@ -77,10 +72,4 @@
     }
 
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Division clone = new Division(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: trunk/sources/HeuristicLab.Functions/Equal.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Equal.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Equal.cs	(revision 155)
@@ -31,5 +31,5 @@
     public override string Description {
       get {
-        return @"Equal condition. Returns 1.0 if both sub-functions evaluate to the same value and 0.0 if they differ.";
+        return @"Equal condition. Returns 1.0 if both sub-trees evaluate to the same value and 0.0 if they differ.";
       }
     }
@@ -40,18 +40,7 @@
     }
 
-    public Equal(Equal source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      if(SubFunctions[0].Evaluate(dataset, sampleIndex) == SubFunctions[1].Evaluate(dataset, sampleIndex)) return 1.0;
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      if(args[0] == args[1]) return 1.0;
       else return 0.0;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Equal clone = new Equal(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Exponential.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Exponential.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Exponential.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Exponential : FunctionBase {
     public override string Description {
-      get { return "Returns returns exponential of the first sub-operator (power(e, x))."; }
+      get { return "Returns returns exponential of the first sub-tree (power(e, x))."; }
     }
 
@@ -39,19 +39,8 @@
       AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
     }
-    public Exponential(Exponential source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Exp(args[0]);
     }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Exp(SubFunctions[0].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Exponential clone = new Exponential(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/FunctionBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/FunctionBase.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/FunctionBase.cs	(revision 155)
@@ -29,305 +29,71 @@
 
 namespace HeuristicLab.Functions {
+  /// <summary>
+  /// Functions are like operators except that they do not allow sub-operators and the normal form of evaluation
+  /// is to evaluate all children first.
+  /// </summary>
   public abstract class FunctionBase : OperatorBase, IFunction {
-    private List<IFunction> subFunctions;
-    // instance subfunctions
-    public IList<IFunction> SubFunctions {
-      get {
-        return subFunctions;
+    
+    public virtual double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      if(tree.SubTrees.Count > 0) {
+        double[] evaluationResults = new double[tree.SubTrees.Count];
+        for(int i = 0; i < evaluationResults.Length; i++) {
+          evaluationResults[i] = tree.SubTrees[i].Evaluate(dataset, sampleIndex);
+        }
+        return Apply(dataset, sampleIndex, evaluationResults);
+      } else {
+        return Apply(dataset, sampleIndex, null);
       }
     }
 
-    // instance variables
-    private List<IVariable> variables;
-    public ICollection<IVariable> LocalVariables {
-      get { return variables.AsReadOnly(); }
+    public abstract double Apply(Dataset dataset, int sampleIndex, double[] args);
+
+    // operator-tree style evaluation is not supported for functions.
+    public override IOperation Apply(IScope scope) {
+      throw new NotSupportedException();
     }
-
-    // reference to the 'type' of the function
-    private FunctionBase metaObject;
-    public IFunction MetaObject {
-      get { return metaObject; }
-    }
-
-    public FunctionBase() {
-      metaObject = this; // (FunctionBase)Activator.CreateInstance(this.GetType());
-      AddVariableInfo(new VariableInfo("Dataset", "Dataset from which to read samples", typeof(DoubleMatrixData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("SampleIndex", "Gives the row index from which to read the sample", typeof(IntData), VariableKind.In));
-      AddVariableInfo(new VariableInfo("Result", "The result of the evaluation of the function", typeof(DoubleData), VariableKind.Out));
-
-      subFunctions = new List<IFunction>();
-      variables = new List<IVariable>();
-    }
-
-    public FunctionBase(FunctionBase source, IDictionary<Guid, object> clonedObjects)
-      : base() {
-      this.metaObject = source.metaObject;
-      variables = new List<IVariable>();
-      subFunctions = new List<IFunction>();
-      foreach (IFunction subFunction in source.SubFunctions) {
-        subFunctions.Add((IFunction)Auxiliary.Clone(subFunction, clonedObjects));
-      }
-      foreach (IVariable variable in source.variables) {
-        variables.Add((IVariable)Auxiliary.Clone(variable, clonedObjects));
-      }
-    }
-
-    public abstract double Evaluate(Dataset dataset, int sampleIndex);
-
-    public override IOperation Apply(IScope scope) {
-      DoubleData result = this.GetVariableValue<DoubleData>("Result", scope, false);
-      Dataset dataset = GetVariableValue<Dataset>("Dataset", scope, true);
-      IntData sampleIndex = GetVariableValue<IntData>("SampleIndex", scope, true);
-      result.Data = Evaluate(dataset, sampleIndex.Data);
-      return null;
-    }
-
     public virtual void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
     }
 
+    private static readonly List<IOperator> emptySubOperatorList = new List<IOperator>();
+    public override IList<IOperator> SubOperators {
+      get { return emptySubOperatorList; }
+    }
+
     public override void AddSubOperator(IOperator subOperator) {
-      subFunctions.Add((IFunction)subOperator);
+      throw new NotSupportedException();
     }
 
     public override bool TryAddSubOperator(IOperator subOperator) {
-      subFunctions.Add((IFunction)subOperator);
-      bool valid = IsValid();
-      if (!valid) {
-        subFunctions.RemoveAt(subFunctions.Count - 1);
-      }
-
-      return valid;
+      throw new NotSupportedException();
     }
 
     public override bool TryAddSubOperator(IOperator subOperator, int index) {
-      subFunctions.Insert(index, (IFunction)subOperator);
-      bool valid = IsValid();
-      if (!valid) {
-        subFunctions.RemoveAt(index);
-      }
-      return valid;
+      throw new NotSupportedException();
     }
 
     public override bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
-      subFunctions.Insert(index, (IFunction)subOperator);
-      bool valid = IsValid(out violatedConstraints);
-      if (!valid) {
-        subFunctions.RemoveAt(index);
-      }
-      return valid;
+      throw new NotSupportedException();
     }
 
     public override bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
-      subFunctions.Add((IFunction)subOperator);
-      bool valid = IsValid(out violatedConstraints);
-      if (!valid) {
-        subFunctions.RemoveAt(subFunctions.Count - 1);
-      }
-
-      return valid;
+      throw new NotSupportedException();
     }
 
     public override void AddSubOperator(IOperator subOperator, int index) {
-      subFunctions.Insert(index, (IFunction)subOperator);
+      throw new NotSupportedException();
     }
 
     public override void RemoveSubOperator(int index) {
-      if (index >= subFunctions.Count) throw new InvalidOperationException();
-      subFunctions.RemoveAt(index);
+      throw new NotSupportedException();
     }
 
-    public override IList<IOperator> SubOperators {
-      get { return subFunctions.ConvertAll(f => (IOperator)f); }
-    }
-
-    public override ICollection<IVariable> Variables {
-      get {
-        List<IVariable> mergedVariables = new List<IVariable>(variables);
-        if (this == metaObject) {
-          foreach (IVariable variable in base.Variables) {
-            if (!IsLocalVariable(variable.Name)) {
-              mergedVariables.Add(variable);
-            }
-          }
-        } else {
-          foreach (IVariable variable in metaObject.Variables) {
-            if (!IsLocalVariable(variable.Name)) {
-              mergedVariables.Add(variable);
-            }
-          }
-        }
-        return mergedVariables;
-      }
-    }
-
-    private bool IsLocalVariable(string name) {
-      foreach (IVariable variable in variables) {
-        if (variable.Name == name) return true;
-      }
-      return false;
-    }
-
-
     public override bool TryRemoveSubOperator(int index) {
-      IFunction removedFunction = subFunctions[index];
-      subFunctions.RemoveAt(index);
-      bool valid = IsValid();
-      if (!valid) {
-        subFunctions.Insert(index, removedFunction);
-      }
-
-      return valid;
+      throw new NotSupportedException();
     }
 
     public override bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
-      IFunction removedFunction = subFunctions[index];
-      subFunctions.RemoveAt(index);
-      bool valid = IsValid(out violatedConstraints);
-      if (!valid) {
-        subFunctions.Insert(index, removedFunction);
-      }
-
-      return valid;
-    }
-
-    public override void AddVariable(IVariable variable) {
-      if (metaObject == this) {
-        base.AddVariable(variable);
-      } else {
-        metaObject.AddVariable(variable);
-      }
-    }
-
-    public override IVariable GetVariable(string name) {
-      foreach (IVariable variable in variables) {
-        if (variable.Name == name) return variable;
-      }
-      if (metaObject == this) {
-        return base.GetVariable(name);
-      } else {
-        return metaObject.GetVariable(name);
-      }
-    }
-
-    public void AddLocalVariable(IVariable variable) {
-      variables.Add(variable);
-    }
-
-    public override void RemoveVariable(string name) {
-      foreach (IVariable variable in variables) {
-        if (variable.Name == name) {
-          variables.Remove(variable);
-          return;
-        }
-      }
-      if (metaObject == this) {
-        base.RemoveVariable(name);
-      } else {
-        metaObject.RemoveVariable(name);
-      }
-    }
-
-    public override IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) {
-      foreach (IVariable variable in Variables) {
-        if (variable.Name == formalName) {
-          return variable.Value;
-        }
-      }
-      return metaObject.GetVariableValue(formalName, scope, recursiveLookup, throwOnError);
-    }
-
-    public override ICollection<IVariableInfo> VariableInfos {
-      get {
-        if (metaObject == this) {
-          return base.VariableInfos;
-        } else {
-          return metaObject.VariableInfos;
-        }
-      }
-    }
-
-    public override void AddVariableInfo(IVariableInfo variableInfo) {
-      if (metaObject == this) {
-        base.AddVariableInfo(variableInfo);
-      } else {
-        metaObject.AddVariableInfo(variableInfo);
-      }
-    }
-
-    public override void RemoveVariableInfo(string formalName) {
-      if (metaObject == this) {
-        base.RemoveVariableInfo(formalName);
-      } else {
-        metaObject.RemoveVariableInfo(formalName);
-      }
-    }
-
-    public override ICollection<IConstraint> Constraints {
-      get {
-        if (metaObject == this) {
-          return base.Constraints;
-        } else {
-          return metaObject.Constraints;
-        }
-      }
-    }
-
-    public override void AddConstraint(IConstraint constraint) {
-      if (metaObject == this) {
-        base.AddConstraint(constraint);
-      } else {
-        metaObject.AddConstraint(constraint);
-      }
-    }
-    public override void RemoveConstraint(IConstraint constraint) {
-      if (metaObject == this) {
-        base.RemoveConstraint(constraint);
-      } else {
-        metaObject.RemoveConstraint(constraint);
-      }
-    }
-
-    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
-      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
-      if (metaObject != this) {
-        XmlNode functionTemplateNode = document.CreateElement("FunctionTemplate");
-        functionTemplateNode.AppendChild(PersistenceManager.Persist(metaObject, document, persistedObjects));
-        node.AppendChild(functionTemplateNode);
-      } 
-
-      // don't need to persist the sub-functions because OperatorBase.GetXmlNode already persisted the sub-operators
-
-      // persist local variables
-      XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "LocalVariables", null);
-      foreach (IVariable variable in variables) {
-        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);
-      XmlNode functionTemplateNode = node.SelectSingleNode("FunctionTemplate");
-      if (functionTemplateNode != null) {
-        metaObject = (FunctionBase)PersistenceManager.Restore(functionTemplateNode.ChildNodes[0], restoredObjects);
-      } else {
-        metaObject = this;
-      }
-      // don't need to explicitly load the sub-functions because that has already been done in OperatorBase.Populate()
-
-      // load local variables
-      XmlNode variablesNode = node.SelectSingleNode("LocalVariables");
-      
-      // remove the variables that have been added in a constructor
-      variables.Clear();
-      // load the persisted variables
-      foreach (XmlNode variableNode in variablesNode.ChildNodes)
-        variables.Add((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
-    }
-
-    public override IView CreateView() {
-      return new FunctionView(this);
+      throw new NotSupportedException();
     }
   }
Index: trunk/sources/HeuristicLab.Functions/FunctionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/FunctionTree.cs	(revision 155)
+++ trunk/sources/HeuristicLab.Functions/FunctionTree.cs	(revision 155)
@@ -0,0 +1,118 @@
+﻿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>();
+    }
+
+    public 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);
+    }
+
+    public double Evaluate(Dataset dataset, int sampleIndex) {
+      return function.Evaluate(dataset, sampleIndex, this);
+    }
+    #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 = (FunctionTree)base.Clone(clonedObjects);
+      foreach(IFunctionTree tree in subTrees) {
+        clone.AddSubTree((IFunctionTree)tree.Clone(clonedObjects));
+      }
+      foreach(IVariable variable in localVariables) {
+        clone.AddVariable((IVariable)variable.Clone(clonedObjects));
+      }
+      clone.function = function;
+      return clone;
+    }
+
+    public override IView CreateView() {
+      return new FunctionTreeView(this);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Functions/FunctionView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/FunctionView.Designer.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/FunctionView.Designer.cs	(revision 155)
@@ -22,5 +22,5 @@
 using System;
 namespace HeuristicLab.Functions {
-  partial class FunctionView {
+  partial class FunctionTreeView {
     /// <summary> 
     /// Required designer variable.
@@ -167,10 +167,10 @@
             this.copyToClipboardMenuItem});
       this.treeNodeContextMenu.Name = "treeNodeContextMenu";
-      this.treeNodeContextMenu.Size = new System.Drawing.Size(259, 26);
+      this.treeNodeContextMenu.Size = new System.Drawing.Size(248, 26);
       // 
       // copyToClipboardMenuItem
       // 
       this.copyToClipboardMenuItem.Name = "copyToClipboardMenuItem";
-      this.copyToClipboardMenuItem.Size = new System.Drawing.Size(258, 22);
+      this.copyToClipboardMenuItem.Size = new System.Drawing.Size(247, 22);
       this.copyToClipboardMenuItem.Text = "Copy to clip-board (Model-Analyzer)";
       this.copyToClipboardMenuItem.Click += new System.EventHandler(this.copyToClipboardMenuItem_Click);
Index: trunk/sources/HeuristicLab.Functions/FunctionView.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/FunctionView.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/FunctionView.cs	(revision 155)
@@ -30,21 +30,22 @@
 using HeuristicLab.Core;
 using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Functions {
-  public partial class FunctionView : ViewBase {
-    private IFunction function;
-
-    private IFunction selectedFunction;
+  public partial class FunctionTreeView : ViewBase {
+    private IFunctionTree functionTree;
+
+    private IFunctionTree selectedBranch;
     private IVariable selectedVariable;
 
     private FunctionNameVisitor functionNameVisitor;
-    public FunctionView() {
+    public FunctionTreeView() {
       InitializeComponent();
       functionNameVisitor = new FunctionNameVisitor();
     }
 
-    public FunctionView(IFunction function)
+    public FunctionTreeView(IFunctionTree functionTree)
       : this() {
-      this.function = function;
+      this.functionTree = functionTree;
       Refresh();
     }
@@ -52,28 +53,28 @@
     protected override void UpdateControls() {
       functionTreeView.Nodes.Clear();
-      function.Accept(functionNameVisitor);
+      functionNameVisitor.Visit(functionTree);
       TreeNode rootNode = new TreeNode();
-      rootNode.Name = function.Name;
+      rootNode.Name = functionTree.Function.Name;
       rootNode.Text = functionNameVisitor.Name;
-      rootNode.Tag = function;
+      rootNode.Tag = functionTree;
       rootNode.ContextMenuStrip = treeNodeContextMenu;
       functionTreeView.Nodes.Add(rootNode);
 
-      foreach(IFunction subFunction in function.SubFunctions) {
-        CreateTree(rootNode, subFunction);
+      foreach(IFunctionTree subTree in functionTree.SubTrees) {
+        CreateTree(rootNode, subTree);
       }
       functionTreeView.ExpandAll();
     }
 
-    private void CreateTree(TreeNode rootNode, IFunction function) {
+    private void CreateTree(TreeNode rootNode, IFunctionTree functionTree) {
       TreeNode node = new TreeNode();
-      function.Accept(functionNameVisitor);
-      node.Tag = function;
-      node.Name = function.Name;
+      functionNameVisitor.Visit(functionTree);
+      node.Name = functionTree.Function.Name;
       node.Text = functionNameVisitor.Name;
+      node.Tag = functionTree;
       node.ContextMenuStrip = treeNodeContextMenu;
       rootNode.Nodes.Add(node);
-      foreach(IFunction subFunction in function.SubFunctions) {
-        CreateTree(node, subFunction);
+      foreach(IFunctionTree subTree in functionTree.SubTrees) {
+        CreateTree(node, subTree);
       }
     }
@@ -85,14 +86,14 @@
       editButton.Enabled = false;
       if(functionTreeView.SelectedNode != null && functionTreeView.SelectedNode.Tag != null) {
-        IFunction selectedFunction = (IFunction)functionTreeView.SelectedNode.Tag;
-        UpdateVariablesList(selectedFunction);
-        templateTextBox.Text = selectedFunction.MetaObject.Name;
-        this.selectedFunction = selectedFunction;
+        IFunctionTree selectedBranch = (IFunctionTree)functionTreeView.SelectedNode.Tag;
+        UpdateVariablesList(selectedBranch);
+        templateTextBox.Text = selectedBranch.Function.Name;
+        this.selectedBranch = selectedBranch;
         editButton.Enabled = true;
       }
     }
 
-    private void UpdateVariablesList(IFunction function) {
-      foreach(IVariable variable in function.LocalVariables) {
+    private void UpdateVariablesList(IFunctionTree functionTree) {
+      foreach(IVariable variable in functionTree.LocalVariables) {
         variablesListBox.Items.Add(variable.Name);
       }
@@ -106,5 +107,5 @@
       if(variablesListBox.SelectedItem != null) {
         string selectedVariableName = (string)variablesListBox.SelectedItem;
-        selectedVariable = selectedFunction.GetVariable(selectedVariableName);
+        selectedVariable = selectedBranch.GetLocalVariable(selectedVariableName);
         variablesSplitContainer.Panel2.Controls.Clear();
         Control editor = (Control)selectedVariable.CreateView();
@@ -121,12 +122,11 @@
       if(functionTreeView.SelectedNode != null && functionTreeView.SelectedNode.Tag != null) {
         TreeNode node = functionTreeView.SelectedNode;
-        selectedFunction.Accept(functionNameVisitor);
+        functionNameVisitor.Visit(selectedBranch);
         node.Text = functionNameVisitor.Name;
       }
     }
 
-    private void editButton_Click(object sender, EventArgs e) {
-      OperatorBaseView operatorView = new OperatorBaseView(selectedFunction.MetaObject);
-      PluginManager.ControlManager.ShowControl(operatorView);
+    protected virtual void editButton_Click(object sender, EventArgs e) {
+      PluginManager.ControlManager.ShowControl(selectedBranch.Function.CreateView());
     }
 
@@ -136,5 +136,5 @@
 
       ModelAnalyzerExportVisitor visitor = new ModelAnalyzerExportVisitor();
-      ((IFunction)node.Tag).Accept(visitor);
+      visitor.Visit((IFunctionTree)node.Tag);
       Clipboard.SetText(visitor.ModelAnalyzerPrefix);
     }
@@ -142,4 +142,5 @@
     private class FunctionNameVisitor : IFunctionVisitor {
       string name;
+      IFunctionTree currentBranch;
 
       public string Name {
@@ -147,6 +148,10 @@
       }
 
+      public void Visit(IFunctionTree tree) {
+        currentBranch = tree;
+        tree.Function.Accept(this);
+      }
+
       #region IFunctionVisitor Members
-
       public void Visit(IFunction function) {
         name = function.Name;
@@ -158,5 +163,5 @@
 
       public void Visit(Constant constant) {
-        name = constant.Value + "";
+        name = ((ConstrainedDoubleData)(currentBranch.GetLocalVariable(HeuristicLab.Functions.Constant.VALUE).Value)).Data + "";
       }
 
@@ -207,12 +212,15 @@
       public void Visit(Variable variable) {
         string timeOffset = "";
-        if(variable.SampleOffset < 0) {
-          timeOffset = "(t" + variable.SampleOffset + ")";
-        } else if(variable.SampleOffset > 0) {
-          timeOffset = "(t+" + variable.SampleOffset + ")";
+        int sampleOffset = ((ConstrainedIntData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.OFFSET).Value).Data;
+        int variableIndex = ((ConstrainedIntData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.INDEX).Value).Data;
+        double weight = ((ConstrainedDoubleData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.WEIGHT).Value).Data;
+        if(sampleOffset < 0) {
+          timeOffset = "(t" + sampleOffset + ")";
+        } else if(sampleOffset > 0) {
+          timeOffset = "(t+" + sampleOffset + ")";
         } else {
           timeOffset = "";
         }
-        name = "Var" + variable.VariableIndex + timeOffset + " * " + variable.Weight;
+        name = "Var" + variableIndex + timeOffset + " * " + weight;
       }
 
@@ -255,4 +263,5 @@
       private string prefix;
       private string currentIndend = "";
+      private IFunctionTree currentBranch;
       public string ModelAnalyzerPrefix {
         get { return prefix; }
@@ -263,112 +272,120 @@
 
       private void VisitFunction(string name, IFunction f) {
-        prefix += currentIndend + "[F]"+name+"(\n";
+        prefix += currentIndend + "[F]" + name + "(\n";
+      }
+
+      #region IFunctionVisitor Members
+
+      public void Visit(IFunction function) {
+        prefix += function.Name;
+      }
+
+      public void Visit(Addition addition) {
+        VisitFunction("Addition[0]", addition);
+      }
+
+      public void Visit(Constant constant) {
+        double value = ((ConstrainedDoubleData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Constant.VALUE).Value).Data;
+        prefix += currentIndend + "[T]Constant(" + value + ";0;0)";
+      }
+
+      public void Visit(Cosinus cosinus) {
+        VisitFunction("Trigonometrics[1]", cosinus);
+      }
+
+      public void Visit(Division division) {
+        VisitFunction("Division[0]", division);
+      }
+
+      public void Visit(Exponential exponential) {
+        VisitFunction("Exponential[0]", exponential);
+      }
+
+      public void Visit(Logarithm logarithm) {
+        VisitFunction("Logarithm[0]", logarithm);
+      }
+
+      public void Visit(Multiplication multiplication) {
+        VisitFunction("Multiplication[0]", multiplication);
+      }
+
+      public void Visit(Power power) {
+        VisitFunction("Power[0]", power);
+      }
+
+      public void Visit(Signum signum) {
+        VisitFunction("Signum[0]", signum);
+      }
+
+      public void Visit(Sinus sinus) {
+        VisitFunction("Trigonometrics[0]", sinus);
+      }
+
+      public void Visit(Sqrt sqrt) {
+        VisitFunction("Sqrt[0]", sqrt);
+      }
+
+      public void Visit(Substraction substraction) {
+        VisitFunction("Substraction[0]", substraction);
+      }
+
+      public void Visit(Tangens tangens) {
+        VisitFunction("Trigonometrics[2]", tangens);
+      }
+
+      public void Visit(HeuristicLab.Functions.Variable variable) {
+        double weight = ((ConstrainedDoubleData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.WEIGHT).Value).Data;
+        double index = ((ConstrainedIntData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.INDEX).Value).Data;
+        double offset = ((ConstrainedIntData)currentBranch.GetLocalVariable(HeuristicLab.Functions.Variable.OFFSET).Value).Data;
+
+        prefix += currentIndend + "[T]Variable(" + weight + ";" + index + ";" + -offset + ")";
+      }
+
+      public void Visit(And and) {
+        VisitFunction("Logical[0]", and);
+      }
+
+      public void Visit(Average average) {
+        VisitFunction("N/A (average)", average);
+      }
+
+      public void Visit(IfThenElse ifThenElse) {
+        VisitFunction("Conditional[0]", ifThenElse);
+      }
+
+      public void Visit(Not not) {
+        VisitFunction("Logical[2]", not);
+      }
+
+      public void Visit(Or or) {
+        VisitFunction("Logical[1]", or);
+      }
+
+      public void Visit(Xor xor) {
+        VisitFunction("N/A (xor)", xor);
+      }
+
+      public void Visit(Equal equal) {
+        VisitFunction("Boolean[2]", equal);
+      }
+
+      public void Visit(LessThan lessThan) {
+        VisitFunction("Boolean[0]", lessThan);
+      }
+      #endregion
+
+      public void Visit(IFunctionTree functionTree) {
+        currentBranch = functionTree;
+        functionTree.Function.Accept(this);
         currentIndend += "  ";
-        foreach(IFunction subFunction in f.SubFunctions) {
-          subFunction.Accept(this);
+        foreach(IFunctionTree subTree in functionTree.SubTrees) {
+          Visit(subTree);
           prefix += ";\n";
         }
-        prefix = prefix.TrimEnd(';','\n');
+        prefix = prefix.TrimEnd(';', '\n');
         prefix += ")";
         currentIndend = currentIndend.Remove(0, 2);
       }
-
-      #region IFunctionVisitor Members
-
-      public void Visit(IFunction function) {
-        prefix += function.Name;
-      }
-
-      public void Visit(Addition addition) {
-        VisitFunction("Addition[0]", addition);
-      }
-
-      public void Visit(Constant constant) {
-        prefix += currentIndend + "[T]Constant(" + constant.Value.Data.ToString() + ";0;0)";
-      }
-
-      public void Visit(Cosinus cosinus) {
-        VisitFunction("Trigonometrics[1]", cosinus);
-      }
-
-      public void Visit(Division division) {
-        VisitFunction("Division[0]", division);
-      }
-
-      public void Visit(Exponential exponential) {
-        VisitFunction("Exponential[0]", exponential);
-      }
-
-      public void Visit(Logarithm logarithm) {
-        VisitFunction("Logarithm[0]", logarithm);
-      }
-
-      public void Visit(Multiplication multiplication) {
-        VisitFunction("Multiplication[0]", multiplication);
-      }
-
-      public void Visit(Power power) {
-        VisitFunction("Power[0]", power);
-      }
-
-      public void Visit(Signum signum) {
-        VisitFunction("Signum[0]", signum);
-      }
-
-      public void Visit(Sinus sinus) {
-        VisitFunction("Trigonometrics[0]", sinus);
-      }
-
-      public void Visit(Sqrt sqrt) {
-        VisitFunction("Sqrt[0]", sqrt);
-      }
-
-      public void Visit(Substraction substraction) {
-        VisitFunction("Substraction[0]", substraction);
-      }
-
-      public void Visit(Tangens tangens) {
-        VisitFunction("Trigonometrics[2]", tangens);
-      }
-
-      public void Visit(HeuristicLab.Functions.Variable variable) {
-        prefix += currentIndend + "[T]Variable(" + variable.Weight + ";" + variable.VariableIndex + ";" + -variable.SampleOffset + ")";
-      }
-
-      public void Visit(And and) {
-        VisitFunction("Logical[0]", and);
-      }
-
-      public void Visit(Average average) {
-        VisitFunction("N/A (average)", average);
-      }
-
-      public void Visit(IfThenElse ifThenElse) {
-        VisitFunction("Conditional[0]", ifThenElse);
-      }
-
-      public void Visit(Not not) {
-        VisitFunction("Logical[2]", not);
-      }
-
-      public void Visit(Or or) {
-        VisitFunction("Logical[1]", or);
-      }
-
-      public void Visit(Xor xor) {
-        VisitFunction("N/A (xor)", xor);
-      }
-
-      public void Visit(Equal equal) {
-        VisitFunction("Boolean[2]", equal);
-      }
-
-      public void Visit(LessThan lessThan) {
-        VisitFunction("Boolean[0]", lessThan);
-      }
-
-      #endregion
-    }
-
+    }
   }
 }
Index: trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj
===================================================================
--- trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/HeuristicLab.Functions.csproj	(revision 155)
@@ -52,4 +52,7 @@
     <Compile Include="Average.cs" />
     <Compile Include="Constant.cs" />
+    <Compile Include="FunctionTree.cs" />
+    <Compile Include="IFunctionTree.cs" />
+    <Compile Include="ProgrammableFunction.cs" />
     <Compile Include="Equal.cs" />
     <Compile Include="FunctionView.cs">
@@ -99,4 +102,8 @@
       <Name>HeuristicLab.Data</Name>
     </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Operators.Programmable\HeuristicLab.Operators.Programmable.csproj">
+      <Project>{E3CCBFC6-900C-41B6-AFB8-6646DB097435}</Project>
+      <Name>HeuristicLab.Operators.Programmable</Name>
+    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
       <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
Index: trunk/sources/HeuristicLab.Functions/IFunction.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/IFunction.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/IFunction.cs	(revision 155)
@@ -28,8 +28,6 @@
 namespace HeuristicLab.Functions {
   public interface IFunction : IOperator {
-    IList<IFunction> SubFunctions { get;}
-    ICollection<IVariable> LocalVariables { get; }
-    IFunction MetaObject { get; }
-    double Evaluate(Dataset dataset, int sampleIndex);
+    double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree);
+    double Apply(Dataset dataset, int sampleIndex, double[] args);
     void Accept(IFunctionVisitor visitor);
   }
Index: trunk/sources/HeuristicLab.Functions/IFunctionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/IFunctionTree.cs	(revision 155)
+++ trunk/sources/HeuristicLab.Functions/IFunctionTree.cs	(revision 155)
@@ -0,0 +1,42 @@
+#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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.Functions {
+  public interface IFunctionTree : IItem {
+    IList<IFunctionTree> SubTrees { get; }
+    ICollection<IVariable> LocalVariables { get; }
+    IFunction Function { get; }
+    IVariable GetLocalVariable(string name);
+    void AddVariable(IVariable variable);
+    void RemoveVariable(string name);
+    void AddSubTree(IFunctionTree tree);
+    void InsertSubTree(int index, IFunctionTree tree);
+    void RemoveSubTree(int index);
+
+    double Evaluate(Dataset dataset, int sampleIndex);
+  }
+}
Index: trunk/sources/HeuristicLab.Functions/IfThenElse.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/IfThenElse.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/IfThenElse.cs	(revision 155)
@@ -31,6 +31,6 @@
     public override string Description {
       get {
-        return @"Returns the result of the second branch if the first branch evaluates to a value >= 0.5 and the result
-of the third branch if the first branch evaluates to < 0.5.";
+        return @"Returns the result of the second sub-tree if the first sub-tree evaluates to a value < 0.5 and the result
+of the third sub-tree if the first sub-tree evaluates to >= 0.5.";
       }
     }
@@ -41,20 +41,14 @@
     }
 
-    public IfThenElse(IfThenElse source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      double condition = Math.Round(SubFunctions[0].Evaluate(dataset, sampleIndex));
-      if(condition >= .5) return SubFunctions[2].Evaluate(dataset, sampleIndex);
-      else if(condition < .5) return SubFunctions[1].Evaluate(dataset, sampleIndex);
+    // special form
+    public override double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      double condition = Math.Round(tree.SubTrees[0].Evaluate(dataset, sampleIndex));
+      if(condition < .5) return tree.SubTrees[1].Evaluate(dataset, sampleIndex);
+      else if(condition >= .5) return tree.SubTrees[2].Evaluate(dataset, sampleIndex);
       else return double.NaN;
     }
 
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      IfThenElse clone = new IfThenElse(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotImplementedException();
     }
 
Index: trunk/sources/HeuristicLab.Functions/LessThan.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/LessThan.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/LessThan.cs	(revision 155)
@@ -31,5 +31,5 @@
     public override string Description {
       get {
-        return @"Less-than condition. Returns 1.0 if the value of the first sub-function is less than the value of the second sub-function and 0.0 otherwise.";
+        return @"Less-than condition. Returns 1.0 if the value of the first sub-tree is less than the value of the second sub-tree and 0.0 otherwise.";
       }
     }
@@ -40,18 +40,7 @@
     }
 
-    public LessThan(LessThan source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      if(SubFunctions[0].Evaluate(dataset, sampleIndex) < SubFunctions[1].Evaluate(dataset, sampleIndex)) return 1.0;
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      if(args[0] < args[1]) return 1.0;
       else return 0.0;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      LessThan clone = new LessThan(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Logarithm.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Logarithm.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Logarithm.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Logarithm : FunctionBase {
     public override string Description {
-      get { return "Returns the natural (base e) logarithm of the first sub-operator."; }
+      get { return "Returns the natural (base e) logarithm of the first sub-tree."; }
     }
 
@@ -40,16 +40,6 @@
     }
 
-    public Logarithm(Logarithm source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Logarithm clone = new Logarithm(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Log(SubFunctions[0].Evaluate(dataset, sampleIndex));
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Log(args[0]);
     }
 
Index: trunk/sources/HeuristicLab.Functions/Multiplication.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Multiplication.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Multiplication.cs	(revision 155)
@@ -33,5 +33,5 @@
     public override string Description {
       get {
-        return @"Returns the product of the results of all sub-operators.
+        return @"Returns the product of the results of all sub-tree.
   (* 3) => 3
   (* 2 3) => 6
@@ -46,24 +46,13 @@
     }
 
-    public Multiplication(Multiplication source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
+    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 = SubFunctions.Count - 1; i >= 0; i--) {
-        result *= SubFunctions[i].Evaluate(dataset, sampleIndex);
+      for(int i = 0; i < args.Length; i++) {
+        result *= args[i];
       }
       return result;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Multiplication clone = new Multiplication(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Not.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Not.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Not.cs	(revision 155)
@@ -31,5 +31,5 @@
     public override string Description {
       get {
-        return @"Logical NOT operation. Only defined for sub-operator-results 0.0 and 1.0.";
+        return @"Logical NOT operation. Only defined for sub-tree-results 0.0 and 1.0.";
       }
     }
@@ -40,20 +40,9 @@
     }
 
-    public Not(Not source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      double result = Math.Round(SubFunctions[0].Evaluate(dataset, sampleIndex));
+    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 object Clone(IDictionary<Guid, object> clonedObjects) {
-      Not clone = new Not(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Or.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Or.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Or.cs	(revision 155)
@@ -31,5 +31,6 @@
     public override string Description {
       get {
-        return @"Logical OR operation. Only defined for sub-operator-results 0.0 and 1.0.";
+        return @"Logical OR operation. Only defined for sub-tree-results 0.0 and 1.0.
+Special form, evaluation stops at first sub-tree that evaluates to 1.0 (true).";
       }
     }
@@ -40,24 +41,17 @@
     }
 
-    public Or(Or source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      foreach(IFunction subFunction in SubFunctions) {
-        double result = Math.Round(subFunction.Evaluate(dataset, sampleIndex));
-        if(result == 1.0) return 1.0;
+    public override double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      foreach(IFunctionTree subTree in tree.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) {
-      Or clone = new Or(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotImplementedException();
     }
-
     public override void Accept(IFunctionVisitor visitor) {
       visitor.Visit(this);
Index: trunk/sources/HeuristicLab.Functions/Power.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Power.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Power.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Power : FunctionBase {
     public override string Description {
-      get { return "Returns the result of the first sub-operator to the power of the second sub-operator (power(x, y))."; }
+      get { return "Returns the result of the first sub-tree to the power of the second sub-tree (power(x, y))."; }
     }
 
@@ -40,19 +40,7 @@
     }
 
-    public Power(Power source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Pow(args[0], args[1]);
     }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Pow(SubFunctions[0].Evaluate(dataset, sampleIndex), SubFunctions[1].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Power clone = new Power(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs	(revision 155)
+++ trunk/sources/HeuristicLab.Functions/ProgrammableFunction.cs	(revision 155)
@@ -0,0 +1,206 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+using System.Xml;
+using System.Reflection;
+using System.CodeDom;
+using System.CodeDom.Compiler;
+using Microsoft.CSharp;
+using System.IO;
+
+namespace HeuristicLab.Functions {
+  public class ProgrammableFunction : FunctionBase {
+    private MethodInfo evaluateMethod;
+
+    private string myDescription;
+    public override string Description {
+      get { return myDescription; }
+    }
+    private string myCode;
+    public string Code {
+      get { return myCode; }
+      set {
+        if(value != myCode) {
+          myCode = value;
+          evaluateMethod = null;
+          OnCodeChanged();
+        }
+      }
+    }
+
+    public ProgrammableFunction() : base() {
+      myCode = "return 0.0;";
+      myDescription = "A function that can be programmed for arbitrary needs.";
+      evaluateMethod = null;
+    }
+
+    public void SetDescription(string description) {
+      if(description == null)
+        throw new NullReferenceException("description must not be null");
+
+      if(description != myDescription) {
+        myDescription = description;
+        OnDescriptionChanged();
+      }
+    }
+
+    public void Compile() {
+      CodeNamespace ns = new CodeNamespace("HeuristicLab.Functions.CustomFunctions");
+      CodeTypeDeclaration typeDecl = new CodeTypeDeclaration("Function");
+      typeDecl.IsClass = true;
+      typeDecl.TypeAttributes = TypeAttributes.Public;
+
+      CodeMemberMethod method = new CodeMemberMethod();
+      method.Name = "Evaluate";
+      method.ReturnType = new CodeTypeReference(typeof(double));
+      method.Attributes = MemberAttributes.Public | MemberAttributes.Static;
+      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IFunction), "function"));
+      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Dataset), "dataset"));
+      method.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "index"));
+      foreach(IVariableInfo info in VariableInfos)
+        method.Parameters.Add(new CodeParameterDeclarationExpression(info.DataType, info.FormalName));
+      string code = myCode;
+      method.Statements.Add(new CodeSnippetStatement(code));
+      typeDecl.Members.Add(method);
+
+      ns.Types.Add(typeDecl);
+      ns.Imports.Add(new CodeNamespaceImport("System"));
+      ns.Imports.Add(new CodeNamespaceImport("System.Collections.Generic"));
+      ns.Imports.Add(new CodeNamespaceImport("System.Text"));
+      ns.Imports.Add(new CodeNamespaceImport("HeuristicLab.Core"));
+      ns.Imports.Add(new CodeNamespaceImport("HeuristicLab.Functions"));
+      foreach(IVariableInfo variableInfo in VariableInfos)
+        ns.Imports.Add(new CodeNamespaceImport(variableInfo.DataType.Namespace));
+
+      CodeCompileUnit unit = new CodeCompileUnit();
+      unit.Namespaces.Add(ns);
+      CompilerParameters parameters = new CompilerParameters();
+      parameters.GenerateExecutable = false;
+      parameters.GenerateInMemory = true;
+      parameters.IncludeDebugInformation = false;
+      Assembly[] loadedAssemblies = AppDomain.CurrentDomain.GetAssemblies();
+      foreach(Assembly loadedAssembly in loadedAssemblies)
+        parameters.ReferencedAssemblies.Add(loadedAssembly.Location);
+      CodeDomProvider provider = new CSharpCodeProvider();
+      CompilerResults results = provider.CompileAssemblyFromDom(parameters, unit);
+
+      evaluateMethod = null;
+      if(results.Errors.HasErrors) {
+        StringWriter writer = new StringWriter();
+        CodeGeneratorOptions options = new CodeGeneratorOptions();
+        options.BlankLinesBetweenMembers = false;
+        options.ElseOnClosing = true;
+        options.IndentString = "  ";
+        provider.GenerateCodeFromCompileUnit(unit, writer, options);
+        writer.Flush();
+        string[] source = writer.ToString().Split(new string[] { "\r\n" }, StringSplitOptions.None);
+        StringBuilder builder = new StringBuilder();
+        for(int i = 0; i < source.Length; i++)
+          builder.AppendLine((i + 1).ToString("###") + "     " + source[i]);
+        builder.AppendLine();
+        builder.AppendLine();
+        builder.AppendLine();
+        foreach(CompilerError error in results.Errors) {
+          builder.Append("Line " + error.Line.ToString());
+          builder.Append(", Column " + error.Column.ToString());
+          builder.AppendLine(": " + error.ErrorText);
+        }
+        throw new Exception("Compile Errors:\n\n" + builder.ToString());
+      } else {
+        Assembly assembly = results.CompiledAssembly;
+        Type[] types = assembly.GetTypes();
+        evaluateMethod = types[0].GetMethod("Evaluate");
+      }
+    }
+
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      //if(evaluateMethod == null) {
+      //  Compile();
+      //}
+
+      //// collect parameters
+      //object[] parameters = new object[VariableInfos.Count + 3];
+      //parameters[0] = this;
+      //parameters[1] = dataset;
+      //parameters[2] = sampleIndex;
+      //int i = 3;
+      //// all local variables are available in the custom function
+      //foreach(IVariableInfo info in VariableInfos) {
+      //  if(info.Local) {
+      //    parameters[i] = this.GetVariable(info.ActualName);
+      //    i++;
+      //  }
+      //}
+      //return (double)evaluateMethod.Invoke(null, parameters);
+      return 0.0;
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      ProgrammableFunction clone = (ProgrammableFunction)base.Clone(clonedObjects);
+      clone.myDescription = Description;
+      clone.myCode = Code;
+      clone.evaluateMethod = evaluateMethod;
+      return clone;
+    }
+
+    public override void Accept(IFunctionVisitor visitor) {
+      visitor.Visit(this);
+    }
+
+    public event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged() {
+      if(DescriptionChanged != null)
+        DescriptionChanged(this, new EventArgs());
+    }
+    public event EventHandler CodeChanged;
+    protected virtual void OnCodeChanged() {
+      if(CodeChanged != null)
+        CodeChanged(this, new EventArgs());
+    }
+
+    #region Persistence Methods
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      XmlNode descriptionNode = document.CreateNode(XmlNodeType.Element, "Description", null);
+      descriptionNode.InnerText = myDescription;
+      node.AppendChild(descriptionNode);
+      XmlNode codeNode = document.CreateNode(XmlNodeType.Element, "Code", null);
+      codeNode.InnerText = myCode;
+      node.AppendChild(codeNode);
+      return node;
+    }
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      XmlNode descriptionNode = node.SelectSingleNode("Description");
+      myDescription = descriptionNode.InnerText;
+      XmlNode codeNode = node.SelectSingleNode("Code");
+      myCode = codeNode.InnerText;
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Functions/Signum.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Signum.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Signum.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Signum : FunctionBase {
     public override string Description {
-      get { return "Returns the signum of the first sub-operator."; }
+      get { return "Returns the signum of the first sub-tree."; }
     }
 
@@ -40,22 +40,10 @@
     }
 
-    public Signum(Signum source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      double value = SubFunctions[0].Evaluate(dataset, sampleIndex);
+    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 object Clone(IDictionary<Guid, object> clonedObjects) {
-      Signum clone = new Signum(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/Sinus.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Sinus.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Sinus.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Sinus : FunctionBase {
     public override string Description {
-      get { return "Returns the sinus of the first sub-operator."; }
+      get { return "Returns the sinus of the first sub-tree."; }
     }
 
@@ -40,19 +40,7 @@
     }
 
-    public Sinus(Sinus source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Sin(args[0]);
     }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Sin(SubFunctions[0].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Sinus clone = new Sinus(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/Sqrt.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Sqrt.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Sqrt.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Sqrt : FunctionBase {
     public override string Description {
-      get { return "Returns the square root of the first sub-operator."; }
+      get { return "Returns the square root of the first sub-tree."; }
     }
 
@@ -40,19 +40,8 @@
     }
 
-    public Sqrt(Sqrt source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Sqrt(args[0]);
     }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Sqrt(SubFunctions[0].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Sqrt clone = new Sqrt(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/Substraction.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Substraction.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Substraction.cs	(revision 155)
@@ -33,5 +33,5 @@
     public override string Description {
       get {
-        return @"Substracts the results of sub-operators 2..n from the result of the first sub-operator.
+        return @"Substracts the results of sub-tree 2..n from the result of the first sub-tree.
     (- 3) => -3
     (- 2 3) => -1
@@ -46,26 +46,15 @@
     }
 
-    public Substraction(Substraction source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
 
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-
-      if(SubFunctions.Count == 1) {
-        return -SubFunctions[0].Evaluate(dataset, sampleIndex);
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      if(args.Length == 1) {
+        return -args[0];
       } else {
-        double result = SubFunctions[0].Evaluate(dataset, sampleIndex);
-        for(int i = 1; i < SubFunctions.Count; i++) {
-          result -= SubFunctions[i].Evaluate(dataset, sampleIndex);
+        double result = args[0];
+        for(int i = 1; i < args.Length; i++) {
+          result -= args[i];
         }
         return result;
       }
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Substraction clone = new Substraction(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
     }
 
Index: trunk/sources/HeuristicLab.Functions/Tangens.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Tangens.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Tangens.cs	(revision 155)
@@ -31,5 +31,5 @@
   public class Tangens : FunctionBase {
     public override string Description {
-      get { return "Returns the tangens of the first sub-operator."; }
+      get { return "Returns the tangens of the first sub-tree."; }
     }
 
@@ -40,18 +40,7 @@
     }
 
-    public Tangens(Tangens source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      return Math.Tan(args[0]);
     }
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      return Math.Tan(SubFunctions[0].Evaluate(dataset, sampleIndex));
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Tangens clone = new Tangens(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
 
     public override void Accept(IFunctionVisitor visitor) {
Index: trunk/sources/HeuristicLab.Functions/Variable.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Variable.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Variable.cs	(revision 155)
@@ -32,19 +32,7 @@
   public class Variable : FunctionBase {
 
-    private ConstrainedIntData variable;
-    private ConstrainedDoubleData weight;
-    private ConstrainedIntData sampleOffset;
-
-    public double SampleOffset {
-      get { return sampleOffset.Data; }
-    }
-
-    public int VariableIndex {
-      get { return variable.Data; }
-    }
-
-    public double Weight {
-      get { return weight.Data; }
-    }
+    public static readonly string WEIGHT = "Weight";
+    public static readonly string OFFSET = "SampleOffset";
+    public static readonly string INDEX = "Variable";
 
     public override string Description {
@@ -56,59 +44,42 @@
     public Variable()
       : base() {
-      AddVariableInfo(new VariableInfo("Variable", "Index of the variable in the dataset representing this feature", typeof(ConstrainedIntData), VariableKind.None));
-      GetVariableInfo("Variable").Local = true;
-      AddVariableInfo(new VariableInfo("Weight", "Weight is multiplied to the feature value", typeof(ConstrainedDoubleData), VariableKind.None));
-      GetVariableInfo("Weight").Local = true;
-      AddVariableInfo(new VariableInfo("SampleOffset", "SampleOffset is added to the sample index", typeof(ConstrainedIntData), VariableKind.None));
-      GetVariableInfo("SampleOffset").Local = true;
+      AddVariableInfo(new VariableInfo(INDEX, "Index of the variable in the dataset representing this feature", typeof(ConstrainedIntData), VariableKind.None));
+      GetVariableInfo(INDEX).Local = true;
+      AddVariableInfo(new VariableInfo(WEIGHT, "Weight is multiplied to the feature value", typeof(ConstrainedDoubleData), VariableKind.None));
+      GetVariableInfo(WEIGHT).Local = true;
+      AddVariableInfo(new VariableInfo(OFFSET, "SampleOffset is added to the sample index", typeof(ConstrainedIntData), VariableKind.None));
+      GetVariableInfo(OFFSET).Local = true;
 
-      variable = new ConstrainedIntData();
-      AddLocalVariable(new HeuristicLab.Core.Variable("Variable", variable));
-
-      weight = new ConstrainedDoubleData();
+      ConstrainedDoubleData weight = new ConstrainedDoubleData();
       // initialize a totally arbitrary range for the weight = [-20.0, 20.0]
       weight.AddConstraint(new DoubleBoundedConstraint(-20.0, 20.0));
-      AddLocalVariable(new HeuristicLab.Core.Variable("Weight", weight));
+      AddVariable(new HeuristicLab.Core.Variable(WEIGHT, weight));
 
-      sampleOffset = new ConstrainedIntData();
+      ConstrainedIntData variable = new ConstrainedIntData();
+      AddVariable(new HeuristicLab.Core.Variable(INDEX, variable));
+
+      ConstrainedIntData sampleOffset = new ConstrainedIntData();
       // initialize a totally arbitrary default range for sampleoffset = [-10, 10]
       sampleOffset.AddConstraint(new IntBoundedConstraint(0, 0));
-      AddLocalVariable(new HeuristicLab.Core.Variable("SampleOffset", sampleOffset));
+      AddVariable(new HeuristicLab.Core.Variable(OFFSET, sampleOffset));
 
-      // samplefeature can't have suboperators
+      // variable can't have suboperators
       AddConstraint(new NumberOfSubOperatorsConstraint(0, 0));
     }
 
-    public Variable(Variable source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
+    // variable can be evaluated directly
+    // evaluation reads local variables weight, index, offset from function-tree and returns the variable-value * weight
+    public override double Evaluate(Dataset dataset, int sampleIndex, IFunctionTree tree) {
+      double w = ((ConstrainedDoubleData)tree.GetLocalVariable(WEIGHT).Value).Data;
+      int v = ((ConstrainedIntData)tree.GetLocalVariable(INDEX).Value).Data;
+      int offset = ((ConstrainedIntData)tree.GetLocalVariable(OFFSET).Value).Data;
 
-      variable = (ConstrainedIntData)GetVariable("Variable").Value;
-      weight = (ConstrainedDoubleData)GetVariable("Weight").Value;
-      sampleOffset = (ConstrainedIntData)GetVariable("SampleOffset").Value;
+      if(sampleIndex + offset < 0 || sampleIndex + offset >= dataset.Rows) return double.NaN;
+      return w * dataset.GetValue(sampleIndex + offset, v);
     }
 
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Variable clone = new Variable(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
-    }
-
-    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
-      base.Populate(node, restoredObjects);
-
-      variable = (ConstrainedIntData)GetVariable("Variable").Value;
-      weight = (ConstrainedDoubleData)GetVariable("Weight").Value;
-      sampleOffset = (ConstrainedIntData)GetVariable("SampleOffset").Value;
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      // local variables
-      int v = variable.Data;
-      double w = weight.Data;
-      int offset = sampleOffset.Data;
-
-      if(sampleIndex+offset<0 || sampleIndex+offset>=dataset.Rows) return double.NaN;
-      return w * dataset.GetValue(sampleIndex + offset, v);
+    // can't apply a variable
+    public override double Apply(Dataset dataset, int sampleIndex, double[] args) {
+      throw new NotSupportedException();
     }
 
Index: trunk/sources/HeuristicLab.Functions/Xor.cs
===================================================================
--- trunk/sources/HeuristicLab.Functions/Xor.cs	(revision 133)
+++ trunk/sources/HeuristicLab.Functions/Xor.cs	(revision 155)
@@ -31,5 +31,5 @@
     public override string Description {
       get {
-        return @"Logical XOR operation. Only defined for sub-operator-results 0.0 and 1.0.";
+        return @"Logical XOR operation. Only defined for sub-tree-results 0.0 and 1.0.";
       }
     }
@@ -40,23 +40,8 @@
     }
 
-    public Xor(Xor source, IDictionary<Guid, object> clonedObjects)
-      : base(source, clonedObjects) {
-    }
-
-
-    public override double Evaluate(Dataset dataset, int sampleIndex) {
-      double r0 = Math.Round(SubFunctions[0].Evaluate(dataset, sampleIndex));
-      double r1 = Math.Round(SubFunctions[1].Evaluate(dataset, sampleIndex));
-      if((r0 == 0.0 && r1 == 0.0) ||
-        (r0 == 1.0 && r1 == 1.0)) return 0.0;
-      else if((r0 == 0.0 && r1 == 1.0) ||
-        (r0 == 1.0 && r1 == 0.0)) return 1.0;
-      else return double.NaN;
-    }
-
-    public override object Clone(IDictionary<Guid, object> clonedObjects) {
-      Xor clone = new Xor(this, clonedObjects);
-      clonedObjects.Add(clone.Guid, clone);
-      return clone;
+    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;
     }
 
