Index: /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.Functions/BakedFunctionTree.cs	(revision 324)
@@ -132,4 +132,46 @@
     }
 
+    public int Size {
+      get {
+        if(treesExpanded) {
+          int size = 1;
+          foreach(BakedFunctionTree tree in subTrees) {
+            size += tree.Size;
+          }
+          return size;
+        } else 
+        return linearRepresentation.Count;
+      }
+    }
+
+    public int Height {
+      get {
+        if(treesExpanded) {
+          int height = 0;
+          foreach(IFunctionTree subTree in subTrees) {
+            int curHeight = subTree.Height;
+            if(curHeight > height) height = curHeight;
+          }
+          return height+1;
+        } else {
+          int nextBranchStart;
+          return BranchHeight(0, out nextBranchStart);
+        }
+      }
+    }
+
+    private int BranchHeight(int branchStart, out int nextBranchStart) {
+      LightWeightFunction f = linearRepresentation[branchStart];
+      int height = 0;
+      branchStart++;
+      for(int i = 0; i < f.arity; i++) {
+        int curHeight = BranchHeight(branchStart, out nextBranchStart);
+        if(curHeight > height) height = curHeight;
+        branchStart = nextBranchStart;
+      }
+      nextBranchStart = branchStart;
+      return height + 1;
+    }
+
     public IList<IFunctionTree> SubTrees {
       get {
@@ -142,5 +184,5 @@
             int length = BranchLength(branchIndex);
             for(int j = branchIndex; j < branchIndex + length; j++) {
-              subTree.linearRepresentation.Add(linearRepresentation[j].Clone());
+              subTree.linearRepresentation.Add(linearRepresentation[j]);
             }
             branchIndex += length;
Index: /trunk/sources/HeuristicLab.Functions/IFunctionTree.cs
===================================================================
--- /trunk/sources/HeuristicLab.Functions/IFunctionTree.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.Functions/IFunctionTree.cs	(revision 324)
@@ -28,4 +28,6 @@
 namespace HeuristicLab.Functions {
   public interface IFunctionTree : IItem {
+    int Size { get; }
+    int Height { get; }
     IList<IFunctionTree> SubTrees { get; }
     ICollection<IVariable> LocalVariables { get; }
Index: /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/ChangeNodeTypeManipulation.cs	(revision 324)
@@ -96,8 +96,8 @@
         // calculate the height and size difference and 
         // check if the size of the new tree is still in the allowed bounds
-        int oldChildSize = gardener.GetTreeSize(selectedChild);
-        int oldChildHeight = gardener.GetTreeSize(selectedChild);
-        int newChildSize = gardener.GetTreeSize(newFunctionTree);
-        int newChildHeight = gardener.GetTreeHeight(newFunctionTree);
+        int oldChildSize = selectedChild.Size;
+        int oldChildHeight = selectedChild.Height;
+        int newChildSize = newFunctionTree.Size;
+        int newChildHeight = newFunctionTree.Height;
         if((treeHeight.Data - oldChildHeight) + newChildHeight > maxTreeHeight ||
           (treeSize.Data - oldChildSize) + newChildSize > maxTreeSize) {
@@ -118,5 +118,5 @@
         // update size and height
         treeSize.Data = (treeSize.Data - oldChildSize) + newChildSize;
-        treeHeight.Data = gardener.GetTreeHeight(root); // must recalculate height because we can't know wether the manipulated branch was the deepest branch
+        treeHeight.Data = root.Height; // must recalculate height because we can't know wether the manipulated branch was the deepest branch
         // check if whole tree is ok
         Debug.Assert(gardener.IsValidTree(root));
Index: /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/CutOutNodeManipulation.cs	(revision 324)
@@ -74,6 +74,6 @@
         if (root.SubTrees.Count > 0) {
           root = root.SubTrees[random.Next(root.SubTrees.Count)];
-          GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-          GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+          GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+          GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
           // update the variable
           scope.GetVariable(scope.TranslateName("FunctionTree")).Value = root;
@@ -85,6 +85,6 @@
           IFunctionTree newTree;
           newTree = gardener.CreateRandomTree(gardener.Terminals, 1, 1);
-          GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree);
-          GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree);
+          GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+          GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
           // update the variable
           scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
@@ -107,6 +107,6 @@
         Debug.Assert(gardener.IsValidTree(root));
         // update the size and height of our tree
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
         // don't need to schedule initialization operations
         return null;
@@ -118,10 +118,10 @@
         parent.RemoveSubTree(childIndex);
         // then determine the number of nodes left over after the child has been removed!
-        int remainingNodes = gardener.GetTreeSize(root);
+        int remainingNodes = root.Size;
         allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
         IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel);
         parent.InsertSubTree(childIndex, newFunctionTree);
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
         Debug.Assert(gardener.IsValidTree(root));
         // schedule an initialization operation for the new function-tree
Index: /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/DeleteSubTreeManipulation.cs	(revision 324)
@@ -64,6 +64,6 @@
         Debug.Assert(gardener.IsValidTree(newTree));
         // update sizes to match the new tree
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
         scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
 
@@ -86,6 +86,6 @@
 
         Debug.Assert(gardener.IsValidTree(root));
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
         // root hasn't changed so don't need to update 'FunctionTree' variable
         return null;
@@ -97,6 +97,6 @@
         parent.InsertSubTree(childIndex, newFunctionTree);
         Debug.Assert(gardener.IsValidTree(root));
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
         // again the root hasn't changed so we don't need to update the 'FunctionTree' variable
         // but we have to return an initialization operation for the newly created tree
Index: /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/Manipulation/SubstituteSubTreeManipulation.cs	(revision 324)
@@ -65,6 +65,6 @@
 
         // update the variables in the scope with the new values
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(newTree);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(newTree);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
         scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
         
@@ -86,5 +86,5 @@
         int parentLevel = gardener.GetBranchLevel(root, parent);
         int maxSubTreeHeight = maxTreeHeight - parentLevel;
-        int maxSubTreeSize = maxTreeSize - (treeSize - gardener.GetTreeSize(parent.SubTrees[childIndex]));
+        int maxSubTreeSize = maxTreeSize - (treeSize - parent.SubTrees[childIndex].Size);
 
         // create a random function tree
@@ -95,6 +95,6 @@
         Debug.Assert(gardener.IsValidTree(root));
         // update the values of treeSize and treeHeight
-        GetVariableValue<IntData>("TreeSize", scope, true).Data = gardener.GetTreeSize(root);
-        GetVariableValue<IntData>("TreeHeight", scope, true).Data = gardener.GetTreeHeight(root);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
         // the root hasn't changed so we don't need to update 
         // return a CompositeOperation that randomly initializes all nodes of the new subtree
Index: /trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/ProbabilisticTreeCreator.cs	(revision 324)
@@ -58,6 +58,6 @@
       IFunctionTree root = gardener.PTC2(random, treeSize, maxTreeHeight);
 
-      int actualTreeSize = gardener.GetTreeSize(root);
-      int actualTreeHeight = gardener.GetTreeHeight(root);
+      int actualTreeSize = root.Size;
+      int actualTreeHeight = root.Height;
 
       scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
Index: /trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/RampedTreeCreator.cs	(revision 324)
@@ -63,6 +63,6 @@
       }
 
-      int actualTreeSize = gardener.GetTreeSize(root);
-      int actualTreeHeight = gardener.GetTreeHeight(root);
+      int actualTreeSize = root.Size;
+      int actualTreeHeight = root.Height;
 
       scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
Index: /trunk/sources/HeuristicLab.StructureIdentification/Recombination/SizeFairCrossOver.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/Recombination/SizeFairCrossOver.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/Recombination/SizeFairCrossOver.cs	(revision 324)
@@ -89,6 +89,6 @@
 
 
-      int newTreeSize = gardener.GetTreeSize(newTree);
-      int newTreeHeight = gardener.GetTreeHeight(newTree);
+      int newTreeSize = newTree.Size;
+      int newTreeHeight = newTree.Height;
       child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
       child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
@@ -133,6 +133,6 @@
 
         // recalculate the size and height of tree1 (the one that we want to insert) because we need to check constraints later on
-        tree1Size = gardener.GetTreeSize(tree1);
-        tree1Height = gardener.GetTreeHeight(tree1);
+        tree1Size = tree1.Size;
+        tree1Height = tree1.Height;
 
         List<int> possibleChildIndices = new List<int>();
@@ -143,5 +143,5 @@
         // find the list of allowed indices (regarding allowed sub-trees, maxTreeSize and maxTreeHeight)
         for(int i = 0; i < tree0.SubTrees.Count; i++) {
-          int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]);
+          int subTreeSize = tree0.SubTrees[i].Size;
 
           // the index is ok when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
@@ -170,6 +170,6 @@
             // go down in node2:
             tree1 = tree1.SubTrees[random.Next(tree1.SubTrees.Count)];
-            tree1Size = gardener.GetTreeSize(tree1);
-            tree1Height = gardener.GetTreeHeight(tree1);
+            tree1Size = tree1.Size;
+            tree1Height = tree1.Height;
           } else {
             // could neither go up or down ... don't know what to do ... give up
@@ -180,5 +180,5 @@
           possibleChildIndices.Clear();
           for(int i = 0; i < tree0.SubTrees.Count; i++) {
-            int subTreeSize = gardener.GetTreeSize(tree0.SubTrees[i]);
+            int subTreeSize = tree0.SubTrees[i].Size;
 
             // when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
Index: /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs
===================================================================
--- /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 323)
+++ /trunk/sources/HeuristicLab.StructureIdentification/TreeGardener.cs	(revision 324)
@@ -241,12 +241,12 @@
 
     #region tree information gathering
-    internal int GetTreeSize(IFunctionTree tree) {
-      return 1 + tree.SubTrees.Sum(f => GetTreeSize(f));
-    }
-
-    internal int GetTreeHeight(IFunctionTree tree) {
-      if(tree.SubTrees.Count == 0) return 1;
-      return 1 + tree.SubTrees.Max(f => GetTreeHeight(f));
-    }
+    //internal int GetTreeSize(IFunctionTree tree) {
+    //  return 1 + tree.SubTrees.Sum(f => GetTreeSize(f));
+    //}
+
+    //internal int GetTreeHeight(IFunctionTree tree) {
+    //  if(tree.SubTrees.Count == 0) return 1;
+    //  return 1 + tree.SubTrees.Max(f => GetTreeHeight(f));
+    //}
 
     internal IFunctionTree GetRandomParentNode(IFunctionTree tree) {
