Index: branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab 3.3.sln	(revision 5686)
@@ -1766,20 +1766,20 @@
 		{C268DA4C-4004-47DA-AF23-44C983281A68} = {2F5318D7-9CC2-4B5A-A7FE-43985FEA7198}
 		{236459CE-80CF-4991-972F-DE74C826BCCC} = {2F5318D7-9CC2-4B5A-A7FE-43985FEA7198}
+		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{6F42C5F8-16CD-43EE-8208-FD4573A69D85} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{70DFD984-B1D9-46FE-8EB7-4DE92D71A9FC} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{BDF86B1D-630E-4CE2-8A49-8C90B1BDE4C9} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{8824925E-3E00-4543-8293-7DDACE4737F8} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{799B0B38-E384-4A17-A73C-F211EB854592} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{5A4679EF-A8F3-4647-B722-441A36B3BA6B} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{A8D5676D-9662-437A-B44D-ECB4046CDE12} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{E86E215D-E3CE-4244-978D-555D4E17AC09} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{1778134B-866B-4CB3-BFC0-52B2FAAA5777} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
+		{125D3006-67F5-48CB-913E-73C0548F17FA} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
 		{FC841674-62A7-4055-BE91-E41944B6C606} = {91243D2B-77EB-4922-BEB0-78C6AB1DEEDC}
 		{DE69A359-A5B8-4D3D-BA8D-D5780D7F96D6} = {91243D2B-77EB-4922-BEB0-78C6AB1DEEDC}
-		{70DFD984-B1D9-46FE-8EB7-4DE92D71A9FC} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{30DD3DA2-CA57-49DD-A5BA-50CEF19DB45F} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{F5C0ECAC-EDBA-4024-872A-1F74AFCB20B4} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{BDF86B1D-630E-4CE2-8A49-8C90B1BDE4C9} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{5A4679EF-A8F3-4647-B722-441A36B3BA6B} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{799B0B38-E384-4A17-A73C-F211EB854592} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{E86E215D-E3CE-4244-978D-555D4E17AC09} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{1778134B-866B-4CB3-BFC0-52B2FAAA5777} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{7F038E9A-B91E-4F49-8C27-D47BC86F1220} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{6F42C5F8-16CD-43EE-8208-FD4573A69D85} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{8824925E-3E00-4543-8293-7DDACE4737F8} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{125D3006-67F5-48CB-913E-73C0548F17FA} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
-		{A8D5676D-9662-437A-B44D-ECB4046CDE12} = {CAE8D82D-2945-48A4-8091-FECC24B3D32A}
 	EndGlobalSection
 EndGlobal
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeGrammarView.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeGrammarView.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionTreeGrammarView.cs	(revision 5686)
@@ -70,5 +70,5 @@
         ClearSymbols();
         foreach (Symbol symbol in Content.Symbols) {
-          if (!(symbol is ReadOnlySymbol)) {
+          if (!(symbol is IReadOnlySymbol)) {
             symbol.Changed += new EventHandler(symbol_Changed);
             symbols.Add(symbol, symbol.InitialFrequency > 0.0);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Tests/ProbabilisticTreeCreaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Tests/ProbabilisticTreeCreaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Tests/ProbabilisticTreeCreaterTest.cs	(revision 5686)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Creators;
@@ -30,5 +31,5 @@
   [TestClass]
   public class ProbabilisticTreeCreaterTest {
-    private const int POPULATION_SIZE = 1000;
+    private const int POPULATION_SIZE = 10000;
     private const int MAX_TREE_SIZE = 100;
     private const int MAX_TREE_HEIGHT = 10;
@@ -53,12 +54,18 @@
       var grammar = Grammars.CreateSimpleArithmeticGrammar();
       var random = new MersenneTwister(31415);
+      var stopwatch = new Stopwatch();
+      stopwatch.Start();
       for (int i = 0; i < POPULATION_SIZE; i++) {
         randomTrees.Add(ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_SIZE, MAX_TREE_HEIGHT, 0, 0));
       }
+      stopwatch.Stop();
 
       foreach (var tree in randomTrees) {
         Util.IsValid(tree);
       }
+      double msPerRandomTreeCreation = stopwatch.ElapsedMilliseconds / (double)POPULATION_SIZE;
+
       Console.WriteLine("ProbabilisticTreeCreator: " + Environment.NewLine +
+        msPerRandomTreeCreation + " ms per random tree (~" + Math.Round(1000.0 / (msPerRandomTreeCreation)) + "random trees / s)" + Environment.NewLine +
         Util.GetSizeDistributionString(randomTrees, 105, 5) + Environment.NewLine +
         Util.GetFunctionDistributionString(randomTrees) + Environment.NewLine +
@@ -66,4 +73,5 @@
         Util.GetTerminalDistributionString(randomTrees) + Environment.NewLine
         );
+      Assert.IsTrue(Math.Round(1000.0 / (msPerRandomTreeCreation)) > 2000); // must achieve more than 2000 random trees / s
     }
 
@@ -74,10 +82,17 @@
       var grammar = Grammars.CreateArithmeticAndAdfGrammar();
       var random = new MersenneTwister(31415);
+      var stopwatch = new Stopwatch();
+      stopwatch.Start();
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_SIZE, MAX_TREE_HEIGHT, 3, 3);
+        randomTrees.Add(ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_SIZE, MAX_TREE_HEIGHT, 3, 3));
+      }
+      stopwatch.Stop();
+      foreach (var tree in randomTrees)
         Util.IsValid(tree);
-        randomTrees.Add(tree);
-      }
+
+      double msPerRandomTreeCreation = stopwatch.ElapsedMilliseconds / (double)POPULATION_SIZE;
+
       Console.WriteLine("ProbabilisticTreeCreator: " + Environment.NewLine +
+        msPerRandomTreeCreation + " ms per random tree (~" + Math.Round(1000.0 / (msPerRandomTreeCreation)) + "random trees / s)" + Environment.NewLine +
         Util.GetSizeDistributionString(randomTrees, 105, 5) + Environment.NewLine +
         Util.GetFunctionDistributionString(randomTrees) + Environment.NewLine +
@@ -85,4 +100,6 @@
         Util.GetTerminalDistributionString(randomTrees) + Environment.NewLine
         );
+
+      Assert.IsTrue(Math.Round(1000.0 / (msPerRandomTreeCreation)) > 2000); // must achieve more than 2000 random trees / s
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentCreater.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentCreater.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentCreater.cs	(revision 5686)
@@ -26,6 +26,6 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Parameters;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -126,5 +126,5 @@
                        where node.SubTrees.Count() > 0
                        from subtree in node.SubTrees
-                       select new { Parent = node, ReplacedChildIndex = node.IndexOfSubTree(subtree), ReplacedChild = subtree }).ToList();
+                       select new CutPoint(node, subtree)).ToList();
 
       if (cutPoints.Count() == 0)
@@ -133,7 +133,7 @@
       var selectedCutPoint = cutPoints[random.Next(cutPoints.Count)];
       // replace the branch at the cut point with an argument node
-      var replacedBranch = selectedCutPoint.ReplacedChild;
-      selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ReplacedChildIndex);
-      selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ReplacedChildIndex, newArgumentNode);
+      var replacedBranch = selectedCutPoint.Child;
+      selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ChildIndex);
+      selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ChildIndex, newArgumentNode);
 
       // find all old invocations of the selected ADF and attach a cloned version of the replaced branch (with all argument-nodes expanded)
@@ -167,10 +167,9 @@
       defunBranch.NumberOfArguments++;
       defunBranch.Grammar.AddSymbol(newArgumentNode.Symbol);
-      defunBranch.Grammar.SetMinSubtreeCount(newArgumentNode.Symbol, 0);
-      defunBranch.Grammar.SetMaxSubtreeCount(newArgumentNode.Symbol, 0);
+      defunBranch.Grammar.SetSubtreeCount(newArgumentNode.Symbol, 0, 0);
       // allow the argument as child of any other symbol
       foreach (var symb in defunBranch.Grammar.Symbols)
-        for (int i = 0; i < defunBranch.Grammar.GetMaxSubtreeCount(symb); i++) {
-          defunBranch.Grammar.SetAllowedChild(symb, newArgumentNode.Symbol, i);
+        for (int i = 0; i < defunBranch.Grammar.GetMaximumSubtreeCount(symb); i++) {
+          defunBranch.Grammar.AddAllowedChildSymbol(symb, newArgumentNode.Symbol, i);
         }
       foreach (var subtree in tree.Root.SubTrees) {
@@ -178,9 +177,8 @@
         var matchingSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == defunBranch.FunctionName).SingleOrDefault();
         if (matchingSymbol != null) {
-          subtree.Grammar.SetMinSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments);
-          subtree.Grammar.SetMaxSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments);
-          foreach (var child in subtree.Grammar.GetAllowedSymbols(subtree.Symbol, 0)) {
-            for (int i = 0; i < subtree.Grammar.GetMaxSubtreeCount(matchingSymbol); i++) {
-              subtree.Grammar.SetAllowedChild(matchingSymbol, child, i);
+          subtree.Grammar.SetSubtreeCount(matchingSymbol, defunBranch.NumberOfArguments, defunBranch.NumberOfArguments);
+          foreach (var child in subtree.Grammar.GetAllowedChildSymbols(subtree.Symbol, 0)) {
+            for (int i = 0; i < subtree.Grammar.GetMaximumSubtreeCount(matchingSymbol); i++) {
+              subtree.Grammar.AddAllowedChildSymbol(matchingSymbol, child, i);
             }
           }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDeleter.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDeleter.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDeleter.cs	(revision 5686)
@@ -84,6 +84,5 @@
         var matchingInvokeSymbol = subtree.Grammar.Symbols.OfType<InvokeFunction>().Where(s => s.FunctionName == selectedDefunBranch.FunctionName).SingleOrDefault();
         if (matchingInvokeSymbol != null) {
-          subtree.Grammar.SetMinSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments);
-          subtree.Grammar.SetMaxSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments);
+          subtree.Grammar.SetSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments, selectedDefunBranch.NumberOfArguments);
         }
       }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDuplicater.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDuplicater.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/ArgumentDuplicater.cs	(revision 5686)
@@ -107,10 +107,9 @@
       // register the new argument symbol and increase the number of arguments of the ADF
       selectedDefunBranch.Grammar.AddSymbol(newArgSymbol);
-      selectedDefunBranch.Grammar.SetMinSubtreeCount(newArgSymbol, 0);
-      selectedDefunBranch.Grammar.SetMaxSubtreeCount(newArgSymbol, 0);
+      selectedDefunBranch.Grammar.SetSubtreeCount(newArgSymbol, 0, 0);
       // allow the argument as child of any other symbol
       foreach (var symb in selectedDefunBranch.Grammar.Symbols)
-        for (int i = 0; i < selectedDefunBranch.Grammar.GetMaxSubtreeCount(symb); i++) {
-          selectedDefunBranch.Grammar.SetAllowedChild(symb, newArgSymbol, i);
+        for (int i = 0; i < selectedDefunBranch.Grammar.GetMaximumSubtreeCount(symb); i++) {
+          selectedDefunBranch.Grammar.AddAllowedChildSymbol(symb, newArgSymbol, i);
         }
       selectedDefunBranch.NumberOfArguments++;
@@ -122,9 +121,8 @@
                                     select symb).SingleOrDefault();
         if (matchingInvokeSymbol != null) {
-          subtree.Grammar.SetMinSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments);
-          subtree.Grammar.SetMaxSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments);
-          foreach (var child in subtree.Grammar.GetAllowedSymbols(subtree.Symbol, 0)) {
-            for (int i = 0; i < subtree.Grammar.GetMaxSubtreeCount(matchingInvokeSymbol); i++) {
-              subtree.Grammar.SetAllowedChild(matchingInvokeSymbol, child, i);
+          subtree.Grammar.SetSubtreeCount(matchingInvokeSymbol, selectedDefunBranch.NumberOfArguments, selectedDefunBranch.NumberOfArguments);
+          foreach (var child in subtree.Grammar.GetAllowedChildSymbols(subtree.Symbol, 0)) {
+            for (int i = 0; i < subtree.Grammar.GetMaximumSubtreeCount(matchingInvokeSymbol); i++) {
+              subtree.Grammar.AddAllowedChildSymbol(matchingInvokeSymbol, child, i);
             }
           }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/GrammarModifier.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/GrammarModifier.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/GrammarModifier.cs	(revision 5686)
@@ -21,48 +21,61 @@
 
 using System.Collections.Generic;
+using System.Linq;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   public static class GrammarModifier {
-    public static void AddDynamicSymbol(ISymbolicExpressionTreeGrammar grammar, ISymbol classRepresentative, string symbolName, int nArgs) {
-      var invokeSym = new InvokeFunction(symbolName);
+    internal static void AddInvokeSymbol(ISymbolicExpressionTreeGrammar grammar, string functionName, int nArgs, CutPoint startCutPoint, IEnumerable<CutPoint> argumentCutPoints) {
+      var invokeSym = new InvokeFunction(functionName);
       grammar.AddSymbol(invokeSym);
-      grammar.SetMinSubtreeCount(invokeSym, nArgs);
-      grammar.SetMaxSubtreeCount(invokeSym, nArgs);
-      SetSyntaxConstraints(grammar, classRepresentative, invokeSym);
-    }
+      grammar.SetSubtreeCount(invokeSym, nArgs, nArgs);
 
+      //allow invoke symbol everywhere, where the child of the startCutPoint was allowed
+      foreach (ISymbol parent in grammar.Symbols) {
+        if (grammar.IsAllowedChildSymbol(parent, startCutPoint.Child.Symbol))
+          grammar.AddAllowedChildSymbol(parent, invokeSym);
+        else {
+          for (int i = 0; i < grammar.GetMaximumSubtreeCount(parent); i++) {
+            if (grammar.IsAllowedChildSymbol(parent, startCutPoint.Child.Symbol, i))
+              grammar.AddAllowedChildSymbol(parent, invokeSym, i);
+          }
+        }
+      }
 
-    public static void AddDynamicArguments(ISymbolicExpressionTreeGrammar grammar, ISymbol classRepresentative, IEnumerable<int> argumentIndexes) {
-      foreach (int argIndex in argumentIndexes) {
-        var argSymbol = new Argument(argIndex);
-        grammar.AddSymbol(argSymbol);
-        grammar.SetMinSubtreeCount(argSymbol, 0);
-        grammar.SetMaxSubtreeCount(argSymbol, 0);
-        SetSyntaxConstraints(grammar, classRepresentative, argSymbol);
+      if (nArgs > 0) {
+        //set allowed child symbols of invoke symbol 
+        foreach (ISymbol child in grammar.Symbols) {
+          if (argumentCutPoints.All(x => grammar.IsAllowedChildSymbol(x.Parent.Symbol, child)))
+            grammar.AddAllowedChildSymbol(invokeSym, child);
+          else {
+            int i = 0;
+            foreach (CutPoint argumentCutPoint in argumentCutPoints) {
+              if (grammar.IsAllowedChildSymbol(argumentCutPoint.Parent.Symbol, child, argumentCutPoint.ChildIndex))
+                grammar.AddAllowedChildSymbol(invokeSym, child, i);
+              i++;
+            }
+          }
+        }
       }
     }
 
-    private static void SetSyntaxConstraints(ISymbolicExpressionTreeGrammar grammar, ISymbol classRepresentative, Symbol newSymbol) {
-      // allow symbol as child of the representative first to make sure that the symbol 
-      // is in the list of parents and children
-      for (int i = 0; i < grammar.GetMaxSubtreeCount(classRepresentative); i++) {
-        grammar.SetAllowedChild(classRepresentative, newSymbol, i);
-      }
-      // for all available symbols add the new symbol as allowed child iff the available symbol is an allowed child of the class representative
-      foreach (var parent in grammar.Symbols) {
-        if (grammar.IsAllowedChild(classRepresentative, parent, 0))
-          for (int arg = 0; arg < grammar.GetMaxSubtreeCount(parent); arg++) {
-            grammar.SetAllowedChild(parent, newSymbol, arg);
+    internal static void AddArgumentSymbol(ISymbolicExpressionTreeGrammar originalGrammar, ISymbolicExpressionTreeGrammar grammar, IEnumerable<int> argumentIndexes, IEnumerable<CutPoint> argumentCutPoints) {
+      foreach (var pair in argumentIndexes.Zip(argumentCutPoints, (a, b) => new { Index = a, CutPoint = b })) {
+        var argSymbol = new Argument(pair.Index);
+        grammar.AddSymbol(argSymbol);
+        grammar.SetSubtreeCount(argSymbol, 0, 0);
+
+        foreach (ISymbol parent in originalGrammar.Symbols) {
+          if (parent is StartSymbol || parent is ProgramRootSymbol) continue;
+          if (originalGrammar.IsAllowedChildSymbol(parent, pair.CutPoint.Child.Symbol))
+            grammar.AddAllowedChildSymbol(parent, argSymbol);
+          else {
+            for (int i = 0; i < originalGrammar.GetMaximumSubtreeCount(parent); i++) {
+              if (originalGrammar.IsAllowedChildSymbol(parent, pair.CutPoint.Child.Symbol, i))
+                grammar.AddAllowedChildSymbol(parent, argSymbol, i);
+            }
           }
-      }
-      // for all available symbols add the new symbol as allowed parent iff the available symbol is an allowed child of the class representative
-      foreach (var child in grammar.Symbols) {
-        if (grammar.IsAllowedChild(classRepresentative, child, 0))
-          for (int arg = 0; arg < grammar.GetMaxSubtreeCount(newSymbol); arg++) {
-            grammar.SetAllowedChild(newSymbol, child, arg);
-          }
+        }
       }
     }
-
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineCreater.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineCreater.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineCreater.cs	(revision 5686)
@@ -27,6 +27,6 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Parameters;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -61,5 +61,6 @@
     private SubroutineCreater(bool deserializing) : base(deserializing) { }
     private SubroutineCreater(SubroutineCreater original, Cloner cloner) : base(original, cloner) { }
-    public SubroutineCreater() : base() {
+    public SubroutineCreater()
+      : base() {
       Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "The maximal length (number of nodes) of the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
@@ -109,7 +110,7 @@
 
       // select a random cut point in the selected branch
-      var allCutPoints = from parent in selectedBody.IterateNodesPrefix()
-                         from subtree in parent.SubTrees
-                         select new { Parent = parent, ReplacedBranchIndex = parent.IndexOfSubTree(subtree), ReplacedBranch = subtree };
+      var allCutPoints = (from parent in selectedBody.IterateNodesPrefix()
+                          from subtree in parent.SubTrees
+                          select new CutPoint(parent, subtree)).ToList();
       if (allCutPoints.Count() == 0)
         // no cut points => abort
@@ -118,16 +119,16 @@
       var selectedCutPoint = allCutPoints.SelectRandom(random);
       // select random branches as argument cut-off points (replaced by argument terminal nodes in the function)
-      List<ISymbolicExpressionTreeNode> argumentBranches = SelectRandomArgumentBranches(selectedCutPoint.ReplacedBranch, random, ARGUMENT_CUTOFF_PROBABILITY, maxFunctionArguments);
-      ISymbolicExpressionTreeNode functionBody = selectedCutPoint.ReplacedBranch;
+      List<CutPoint> argumentCutPoints = SelectRandomArgumentBranches(selectedCutPoint.Child, random, ARGUMENT_CUTOFF_PROBABILITY, maxFunctionArguments);
+      ISymbolicExpressionTreeNode functionBody = selectedCutPoint.Child;
       // disconnect the function body from the tree
-      selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ReplacedBranchIndex);
+      selectedCutPoint.Parent.RemoveSubTree(selectedCutPoint.ChildIndex);
       // disconnect the argument branches from the function
-      functionBody = DisconnectBranches(functionBody, argumentBranches);
+      functionBody = DisconnectBranches(functionBody, argumentCutPoints);
       // insert a function invocation symbol instead
       var invokeNode = (InvokeFunctionTreeNode)(new InvokeFunction(newFunctionName)).CreateTreeNode();
-      selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ReplacedBranchIndex, invokeNode);
+      selectedCutPoint.Parent.InsertSubTree(selectedCutPoint.ChildIndex, invokeNode);
       // add the branches selected as argument as subtrees of the function invocation node
-      foreach (var argumentBranch in argumentBranches)
-        invokeNode.AddSubTree(argumentBranch);
+      foreach (var argumentCutPoint in argumentCutPoints)
+        invokeNode.AddSubTree(argumentCutPoint.Child);
 
       // insert a new function defining branch
@@ -138,6 +139,6 @@
       // the grammar in the newly defined function is a clone of the grammar of the originating branch
       defunNode.SetGrammar((ISymbolicExpressionTreeGrammar)selectedBody.Grammar.Clone());
-      // remove all argument symbols from grammar
-      var oldArgumentSymbols = defunNode.Grammar.Symbols.OfType<Argument>().ToList();
+      // remove all argument symbols from grammar except that one contained in cutpoints
+      var oldArgumentSymbols = selectedBody.Grammar.Symbols.OfType<Argument>().ToList();
       foreach (var oldArgSymb in oldArgumentSymbols)
         defunNode.Grammar.RemoveSymbol(oldArgSymb);
@@ -146,15 +147,9 @@
                                 select node.Symbol.ArgumentIndex).Distinct();
       // add argument symbols to grammar of function defining branch
-      GrammarModifier.AddDynamicArguments(defunNode.Grammar, defunNode.Symbol, newArgumentIndexes);
+      GrammarModifier.AddArgumentSymbol(selectedBody.Grammar, defunNode.Grammar, newArgumentIndexes, argumentCutPoints);
       defunNode.NumberOfArguments = newArgumentIndexes.Count();
-      if (defunNode.NumberOfArguments != argumentBranches.Count) throw new InvalidOperationException();
+      if (defunNode.NumberOfArguments != argumentCutPoints.Count) throw new InvalidOperationException();
       // add invoke symbol for newly defined function to the original branch 
-      var allowedParents = from symb in selectedBody.Grammar.Symbols
-                           where !(symb is ProgramRootSymbol)
-                           select symb;
-      var allowedChildren = from symb in selectedBody.Grammar.Symbols
-                            where selectedBody.Grammar.IsAllowedChild(selectedBody.Symbol, symb, 0)
-                            select symb;
-      GrammarModifier.AddDynamicSymbol(selectedBody.Grammar, selectedBody.Symbol, defunNode.FunctionName, defunNode.NumberOfArguments);
+      GrammarModifier.AddInvokeSymbol(selectedBody.Grammar, defunNode.FunctionName, defunNode.NumberOfArguments, selectedCutPoint, argumentCutPoints);
 
       // when the new function body was taken from another function definition
@@ -168,11 +163,5 @@
           // when the original branch can be invoked from the subtree then also allow invocation of the function
           if (originalBranchInvokeSymbol != null) {
-            allowedParents = from symb in subtree.Grammar.Symbols
-                             where !(symb is ProgramRootSymbol)
-                             select symb;
-            allowedChildren = from symb in subtree.Grammar.Symbols
-                              where subtree.Grammar.IsAllowedChild(subtree.Symbol, symb, 0)
-                              select symb;
-            GrammarModifier.AddDynamicSymbol(subtree.Grammar, subtree.Symbol, defunNode.FunctionName, defunNode.NumberOfArguments);
+            GrammarModifier.AddInvokeSymbol(subtree.Grammar, defunNode.FunctionName, defunNode.NumberOfArguments, selectedCutPoint, argumentCutPoints);
           }
         }
@@ -181,7 +170,7 @@
     }
 
-    private static ISymbolicExpressionTreeNode DisconnectBranches(ISymbolicExpressionTreeNode node, List<ISymbolicExpressionTreeNode> argumentBranches) {
-      if (argumentBranches.Contains(node)) {
-        var argumentIndex = argumentBranches.IndexOf(node);
+    private static ISymbolicExpressionTreeNode DisconnectBranches(ISymbolicExpressionTreeNode node, List<CutPoint> argumentCutPoints) {
+      int argumentIndex = argumentCutPoints.FindIndex(x => x.Child == node);
+      if (argumentIndex != -1) {
         var argSymbol = new Argument(argumentIndex);
         return argSymbol.CreateTreeNode();
@@ -192,10 +181,10 @@
       // recursively apply function for subtrees or append a argument terminal node
       foreach (var subtree in subtrees) {
-        node.AddSubTree(DisconnectBranches(subtree, argumentBranches));
+        node.AddSubTree(DisconnectBranches(subtree, argumentCutPoints));
       }
       return node;
     }
 
-    private static List<ISymbolicExpressionTreeNode> SelectRandomArgumentBranches(ISymbolicExpressionTreeNode selectedRoot,
+    private static List<CutPoint> SelectRandomArgumentBranches(ISymbolicExpressionTreeNode selectedRoot,
       IRandom random,
       double cutProbability,
@@ -203,7 +192,7 @@
       // breadth first determination of argument cut-off points
       // we must make sure that we cut off all original argument nodes and that the number of new argument is smaller than the limit
-      List<ISymbolicExpressionTreeNode> argumentBranches = new List<ISymbolicExpressionTreeNode>();
+      List<CutPoint> argumentBranches = new List<CutPoint>();
       if (selectedRoot is ArgumentTreeNode) {
-        argumentBranches.Add(selectedRoot);
+        argumentBranches.Add(new CutPoint(selectedRoot.Parent, selectedRoot));
         return argumentBranches;
       } else {
@@ -213,12 +202,15 @@
                                            select nArgumentsInTree).ToList();
         // determine the minimal number of new argument nodes for each sub-tree
+        //if we exceed the maxArguments return the same cutpoint as the start cutpoint to create a ADF that returns only its argument
         var minNewArgumentsForSubtrees = numberOfArgumentsInSubtrees.Select(x => x > 0 ? 1 : 0).ToList();
         if (minNewArgumentsForSubtrees.Sum() > maxArguments) {
-          argumentBranches.Add(selectedRoot);
+          argumentBranches.Add(new CutPoint(selectedRoot.Parent, selectedRoot));
           return argumentBranches;
         }
         // cut-off in the sub-trees in random order
         var randomIndexes = (from index in Enumerable.Range(0, selectedRoot.SubTrees.Count())
-                             select new { Index = index, OrderValue = random.NextDouble() }).OrderBy(x => x.OrderValue).Select(x => x.Index);
+                             select new { Index = index, OrderValue = random.NextDouble() })
+                             .OrderBy(x => x.OrderValue)
+                             .Select(x => x.Index);
         foreach (var subtreeIndex in randomIndexes) {
           var subtree = selectedRoot.GetSubTree(subtreeIndex);
@@ -237,5 +229,5 @@
           } else {
             // cut-off at current sub-tree
-            argumentBranches.Add(subtree);
+            argumentBranches.Add(new CutPoint(subtree.Parent, subtree));
           }
         }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDeleter.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDeleter.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDeleter.cs	(revision 5686)
@@ -26,5 +26,4 @@
 using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System.Collections.Generic;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -87,28 +86,28 @@
                                 from subtree in node.SubTrees.OfType<InvokeFunctionTreeNode>()
                                 where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
-                                select new { Parent = node, ReplacedChildIndex = node.IndexOfSubTree(subtree), ReplacedChild = subtree }).FirstOrDefault();
+                                select new CutPoint(node, subtree)).FirstOrDefault();
       while (invocationCutPoint != null) {
         // deletion by random regeneration
         ISymbolicExpressionTreeNode replacementTree = null;
-        var allowedSymbolsList = invocationCutPoint.Parent.Grammar.GetAllowedSymbols(invocationCutPoint.Parent.Symbol, invocationCutPoint.ReplacedChildIndex).ToList();
+        var allowedSymbolsList = invocationCutPoint.Parent.Grammar.GetAllowedChildSymbols(invocationCutPoint.Parent.Symbol, invocationCutPoint.ChildIndex).ToList();
         var weights = allowedSymbolsList.Select(s => s.InitialFrequency);
         var selectedSymbol = allowedSymbolsList.SelectRandom(weights, random);
 
-        int minPossibleLength = invocationCutPoint.Parent.Grammar.GetMinExpressionLength(selectedSymbol);
-        int maxLength = Math.Max(minPossibleLength, invocationCutPoint.ReplacedChild.GetLength());
-        int minPossibleDepth = invocationCutPoint.Parent.Grammar.GetMinExpressionDepth(selectedSymbol);
-        int maxDepth = Math.Max(minPossibleDepth, invocationCutPoint.ReplacedChild.GetDepth());
+        int minPossibleLength = invocationCutPoint.Parent.Grammar.GetMinimumExpressionLength(selectedSymbol);
+        int maxLength = Math.Max(minPossibleLength, invocationCutPoint.Child.GetLength());
+        int minPossibleDepth = invocationCutPoint.Parent.Grammar.GetMinimumExpressionDepth(selectedSymbol);
+        int maxDepth = Math.Max(minPossibleDepth, invocationCutPoint.Child.GetDepth());
         replacementTree = selectedSymbol.CreateTreeNode();
         if (replacementTree.HasLocalParameters)
           replacementTree.ResetLocalParameters(random);
-        invocationCutPoint.Parent.RemoveSubTree(invocationCutPoint.ReplacedChildIndex);
-        invocationCutPoint.Parent.InsertSubTree(invocationCutPoint.ReplacedChildIndex, replacementTree);
+        invocationCutPoint.Parent.RemoveSubTree(invocationCutPoint.ChildIndex);
+        invocationCutPoint.Parent.InsertSubTree(invocationCutPoint.ChildIndex, replacementTree);
 
-        ProbabilisticTreeCreator.PTC2(random, replacementTree, maxLength, maxDepth, 0, 0);
+        ProbabilisticTreeCreator.PTC2(random, replacementTree, maxLength, maxDepth);
 
         invocationCutPoint = (from node in symbolicExpressionTree.IterateNodesPrefix()
                               from subtree in node.SubTrees.OfType<InvokeFunctionTreeNode>()
                               where subtree.Symbol.FunctionName == selectedDefunBranch.FunctionName
-                              select new { Parent = node, ReplacedChildIndex = node.IndexOfSubTree(subtree), ReplacedChild = subtree }).FirstOrDefault();
+                              select new CutPoint(node, subtree)).FirstOrDefault();
       }
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDuplicater.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDuplicater.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/ArchitectureManipulators/SubroutineDuplicater.cs	(revision 5686)
@@ -79,5 +79,25 @@
                                     select symb).SingleOrDefault();
         if (matchingInvokeSymbol != null) {
-          GrammarModifier.AddDynamicSymbol(subtree.Grammar, subtree.Symbol, duplicatedDefunBranch.FunctionName, duplicatedDefunBranch.NumberOfArguments);
+          var invokeSymbol = new InvokeFunction(duplicatedDefunBranch.FunctionName);
+          subtree.Grammar.AddSymbol(invokeSymbol);
+          subtree.Grammar.SetSubtreeCount(invokeSymbol, duplicatedDefunBranch.NumberOfArguments, duplicatedDefunBranch.NumberOfArguments);
+
+          foreach (Symbol symbol in subtree.Grammar.Symbols) {
+            if (subtree.Grammar.IsAllowedChildSymbol(symbol, matchingInvokeSymbol))
+              subtree.Grammar.AddAllowedChildSymbol(symbol, invokeSymbol);
+            else {
+              for (int i = 0; i < subtree.Grammar.GetMaximumSubtreeCount(symbol); i++)
+                if (subtree.Grammar.IsAllowedChildSymbol(symbol, matchingInvokeSymbol, i))
+                  subtree.Grammar.AddAllowedChildSymbol(symbol, matchingInvokeSymbol, i);
+            }
+          }
+
+          foreach (Symbol symbol in subtree.Grammar.GetAllowedChildSymbols(matchingInvokeSymbol))
+            if (symbol != invokeSymbol) //avoid duplicate entry invokesymbol / invokesymbol
+              subtree.Grammar.AddAllowedChildSymbol(invokeSymbol, symbol);
+          for (int i = 0; i < subtree.Grammar.GetMaximumSubtreeCount(matchingInvokeSymbol); i++) {
+            foreach (Symbol symbol in subtree.Grammar.GetAllowedChildSymbols(matchingInvokeSymbol, i).Except(subtree.Grammar.GetAllowedChildSymbols(matchingInvokeSymbol)))
+              subtree.Grammar.AddAllowedChildSymbol(invokeSymbol, symbol, i);
+          }
         }
         // in the current subtree:
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Creators/ProbabilisticTreeCreator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Creators/ProbabilisticTreeCreator.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Creators/ProbabilisticTreeCreator.cs	(revision 5686)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using System.Linq;
-using System.Text;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -34,10 +33,8 @@
   [Item("ProbabilisticTreeCreator", "An operator that creates new symbolic expression trees with uniformly distributed length")]
   public class ProbabilisticTreeCreator : SymbolicExpressionTreeCreator,
-    ISymbolicExpressionTreeSizeConstraintOperator, ISymbolicExpressionTreeGrammarBasedOperator, ISymbolicExpressionTreeArchitectureAlteringOperator {
+    ISymbolicExpressionTreeSizeConstraintOperator, ISymbolicExpressionTreeGrammarBasedOperator {
     private const int MAX_TRIES = 100;
     private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
     private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
-    private const string MaximumFunctionDefinitionsParameterName = "MaximumFunctionDefinitions";
-    private const string MaximumFunctionArgumentsParameterName = "MaximumFunctionArguments";
     private const string SymbolicExpressionTreeGrammarParameterName = "SymbolicExpressionTreeGrammar";
     #region Parameter Properties
@@ -48,12 +45,6 @@
       get { return (IValueLookupParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeDepthParameterName]; }
     }
-    public IValueLookupParameter<IntValue> MaximumFunctionDefinitionsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters[MaximumFunctionDefinitionsParameterName]; }
-    }
-    public IValueLookupParameter<IntValue> MaximumFunctionArgumentsParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters[MaximumFunctionArgumentsParameterName]; }
-    }
-    public IValueLookupParameter<ISymbolicExpressionTreeGrammar> SymbolicExpressionTreeGrammarParameter {
-      get { return (IValueLookupParameter<ISymbolicExpressionTreeGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; }
+    public IValueLookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionTreeGrammarParameter {
+      get { return (IValueLookupParameter<ISymbolicExpressionGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; }
     }
     #endregion
@@ -65,11 +56,5 @@
       get { return MaximumSymbolicExpressionTreeDepthParameter.ActualValue; }
     }
-    public IntValue MaximumFunctionDefinitions {
-      get { return MaximumFunctionDefinitionsParameter.ActualValue; }
-    }
-    public IntValue MaximumFunctionArguments {
-      get { return MaximumFunctionArgumentsParameter.ActualValue; }
-    }
-    public ISymbolicExpressionTreeGrammar SymbolicExpressionTreeGrammar {
+    public ISymbolicExpressionGrammar SymbolicExpressionTreeGrammar {
       get { return SymbolicExpressionTreeGrammarParameter.ActualValue; }
     }
@@ -83,7 +68,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, "The maximal length (number of nodes) of the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, "The maximal depth of the symbolic expression tree (a tree with one node has depth = 0)."));
-      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumFunctionDefinitionsParameterName, "The maximum allowed number of automatically defined functions."));
-      Parameters.Add(new ValueLookupParameter<IntValue>(MaximumFunctionArgumentsParameterName, "The maximum allowed number of arguments of automatically defined functions."));
-      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, "The tree grammar that defines the correct syntax of symbolic expression trees that should be created."));
     }
 
@@ -93,17 +76,20 @@
 
     protected override ISymbolicExpressionTree Create(IRandom random) {
-      return Create(random, SymbolicExpressionTreeGrammar, MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value,
-        MaximumFunctionDefinitions.Value, MaximumFunctionArguments.Value);
-    }
-
-    public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionTreeGrammar grammar,
-      int maxTreeLength, int maxTreeDepth,
-      int maxFunctionDefinitions, int maxFunctionArguments
-      ) {
+      return Create(random, SymbolicExpressionTreeGrammar, MaximumSymbolicExpressionTreeLength.Value, MaximumSymbolicExpressionTreeDepth.Value);
+
+    }
+
+    public static ISymbolicExpressionTree Create(IRandom random, ISymbolicExpressionGrammar grammar,
+      int maxTreeLength, int maxTreeDepth) {
       SymbolicExpressionTree tree = new SymbolicExpressionTree();
-      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
+      var rootNode = (SymbolicExpressionTreeTopLevelNode)grammar.ProgramRootSymbol.CreateTreeNode();
       if (rootNode.HasLocalParameters) rootNode.ResetLocalParameters(random);
       rootNode.SetGrammar(new SymbolicExpressionTreeGrammar(grammar));
-      tree.Root = PTC2(random, rootNode, maxTreeLength, maxTreeDepth, maxFunctionDefinitions, maxFunctionArguments);
+      var startNode = (SymbolicExpressionTreeTopLevelNode)grammar.StartSymbol.CreateTreeNode();
+      startNode.SetGrammar(new SymbolicExpressionTreeGrammar(grammar));
+      if (startNode.HasLocalParameters) startNode.ResetLocalParameters(random);
+      rootNode.AddSubTree(startNode);
+      PTC2(random, startNode, maxTreeLength, maxTreeDepth);
+      tree.Root = rootNode;
       return tree;
     }
@@ -115,9 +101,9 @@
     }
 
-    public static ISymbolicExpressionTreeNode PTC2(IRandom random, ISymbolicExpressionTreeNode seedNode,
-      int maxLength, int maxDepth, int maxFunctionDefinitions, int maxFunctionArguments) {
+    public static void PTC2(IRandom random, ISymbolicExpressionTreeNode seedNode,
+      int maxLength, int maxDepth) {
       // tree length is limited by the grammar and by the explicit size constraints
-      int allowedMinLength = seedNode.Grammar.GetMinExpressionLength(seedNode.Symbol);
-      int allowedMaxLength = Math.Min(maxLength, seedNode.Grammar.GetMaxExpressionLength(seedNode.Symbol));
+      int allowedMinLength = seedNode.Grammar.GetMinimumExpressionLength(seedNode.Symbol);
+      int allowedMaxLength = Math.Min(maxLength, seedNode.Grammar.GetMaximumExpressionLength(seedNode.Symbol));
       int tries = 0;
       while (tries++ < MAX_TRIES) {
@@ -125,11 +111,11 @@
         int targetTreeLength;
         targetTreeLength = random.Next(allowedMinLength, allowedMaxLength + 1);
-        if (targetTreeLength <= 1 || maxDepth <= 1) return seedNode;
-
-        bool success = CreateFullTreeFromSeed(random, seedNode, seedNode.Grammar, targetTreeLength, maxDepth, maxFunctionDefinitions, maxFunctionArguments);
+        if (targetTreeLength <= 1 || maxDepth <= 1) return;
+
+        bool success = CreateFullTreeFromSeed(random, seedNode, seedNode.Grammar, targetTreeLength, maxDepth);
 
         // if successful => check constraints and return the tree if everything looks ok        
         if (success && seedNode.GetLength() <= maxLength && seedNode.GetDepth() <= maxDepth) {
-          return seedNode;
+          return;
         } else {
           // clean seedNode
@@ -142,7 +128,7 @@
 
     private static bool CreateFullTreeFromSeed(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeGrammar globalGrammar,
-      int targetLength, int maxDepth, int maxFunctionDefinitions, int maxFunctionArguments) {
+      int targetLength, int maxDepth) {
       try {
-        TryCreateFullTreeFromSeed(random, root, globalGrammar, targetLength, maxDepth, maxFunctionDefinitions, maxFunctionArguments);
+        TryCreateFullTreeFromSeed(random, root, globalGrammar, targetLength, maxDepth);
         return true;
       }
@@ -151,8 +137,8 @@
 
     private static void TryCreateFullTreeFromSeed(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeGrammar globalGrammar,
-      int targetLength, int maxDepth, int maxFunctionDefinitions, int maxFunctionArguments) {
+      int targetLength, int maxDepth) {
       List<TreeExtensionPoint> extensionPoints = new List<TreeExtensionPoint>();
       int currentLength = 1;
-      int totalListMinLength = globalGrammar.GetMinExpressionLength(root.Symbol) - 1;
+      int totalListMinLength = globalGrammar.GetMinimumExpressionLength(root.Symbol) - 1;
       int actualArity = SampleArity(random, root, targetLength);
       for (int i = 0; i < actualArity; i++) {
@@ -170,11 +156,11 @@
         int argumentIndex = nextExtension.ChildIndex;
         int extensionDepth = nextExtension.ExtensionPointDepth;
-        if (extensionDepth + parent.Grammar.GetMinExpressionDepth(parent.Symbol) >= maxDepth) {
-          ReplaceWithMinimalTree(random, root, parent, argumentIndex, maxFunctionDefinitions, maxFunctionArguments);
+        if (extensionDepth + parent.Grammar.GetMinimumExpressionDepth(parent.Symbol) >= maxDepth) {
+          ReplaceWithMinimalTree(random, root, parent, argumentIndex);
         } else {
           var allowedSymbols = (from s in parent.Grammar.Symbols
-                                where parent.Grammar.IsAllowedChild(parent.Symbol, s, argumentIndex)
-                                where parent.Grammar.GetMinExpressionDepth(s) + extensionDepth - 1 < maxDepth
-                                where parent.Grammar.GetMaxExpressionLength(s) > targetLength - totalListMinLength - currentLength
+                                where parent.Grammar.IsAllowedChildSymbol(parent.Symbol, s, argumentIndex)
+                                where parent.Grammar.GetMinimumExpressionDepth(s) + extensionDepth - 1 < maxDepth
+                                where parent.Grammar.GetMaximumExpressionLength(s) > targetLength - totalListMinLength - currentLength
                                 select s)
                                .ToList();
@@ -186,5 +172,7 @@
           parent.InsertSubTree(argumentIndex, newTree);
 
-          InitializeNewTreeNode(random, root, newTree, maxFunctionDefinitions, maxFunctionArguments);
+          var topLevelNode = newTree as SymbolicExpressionTreeTopLevelNode;
+          if (topLevelNode != null)
+            topLevelNode.SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone());
 
           currentLength++;
@@ -198,5 +186,5 @@
             extensionPoints.Add(new TreeExtensionPoint { Parent = newTree, ChildIndex = i, ExtensionPointDepth = extensionDepth + 1 });
           }
-          totalListMinLength += newTree.Grammar.GetMinExpressionLength(newTree.Symbol);
+          totalListMinLength += newTree.Grammar.GetMinimumExpressionLength(newTree.Symbol);
         }
       }
@@ -209,13 +197,13 @@
         int a = nextExtension.ChildIndex;
         int d = nextExtension.ExtensionPointDepth;
-        ReplaceWithMinimalTree(random, root, parent, a, maxFunctionDefinitions, maxFunctionArguments);
+        ReplaceWithMinimalTree(random, root, parent, a);
       }
     }
 
     private static void ReplaceWithMinimalTree(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode parent,
-      int argumentIndex, int maxFunctionDefinitions, int maxFunctionArguments) {
+      int childIndex) {
       // determine possible symbols that will lead to the smallest possible tree
-      var possibleSymbols = (from s in parent.Grammar.GetAllowedSymbols(parent.Symbol, argumentIndex)
-                             group s by parent.Grammar.GetMinExpressionLength(s) into g
+      var possibleSymbols = (from s in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, childIndex)
+                             group s by parent.Grammar.GetMinimumExpressionLength(s) into g
                              orderby g.Key
                              select g).First().ToList();
@@ -224,56 +212,17 @@
       var tree = selectedSymbol.CreateTreeNode();
       if (tree.HasLocalParameters) tree.ResetLocalParameters(random);
-      parent.RemoveSubTree(argumentIndex);
-      parent.InsertSubTree(argumentIndex, tree);
-      InitializeNewTreeNode(random, root, tree, maxFunctionDefinitions, maxFunctionArguments);
-      for (int i = 0; i < tree.Grammar.GetMinSubtreeCount(tree.Symbol); i++) {
+      parent.RemoveSubTree(childIndex);
+      parent.InsertSubTree(childIndex, tree);
+
+      var topLevelNode = tree as SymbolicExpressionTreeTopLevelNode;
+      if (topLevelNode != null)
+        topLevelNode.SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone());
+
+      for (int i = 0; i < tree.Grammar.GetMinimumSubtreeCount(tree.Symbol); i++) {
         // insert a dummy sub-tree and add the pending extension to the list
         var dummy = new SymbolicExpressionTreeNode();
         tree.AddSubTree(dummy);
         // replace the just inserted dummy by recursive application
-        ReplaceWithMinimalTree(random, root, tree, i, maxFunctionDefinitions, maxFunctionArguments);
-      }
-    }
-
-    private static void InitializeNewTreeNode(IRandom random, ISymbolicExpressionTreeNode root, ISymbolicExpressionTreeNode newTree, int maxFunctionDefinitions, int maxFunctionArguments) {
-      // NB it is assumed that defuns are only allowed as children of root and nowhere else
-      // also assumes that newTree is already attached to root somewhere
-      if (IsTopLevelBranch(root, newTree)) {
-        ((SymbolicExpressionTreeTopLevelNode)newTree).SetGrammar((ISymbolicExpressionTreeGrammar)root.Grammar.Clone());
-
-        // allow invokes of existing ADFs with higher index
-        int argIndex = root.IndexOfSubTree(newTree);
-        for (int i = argIndex + 1; i < root.SubTrees.Count(); i++) {
-          var otherDefunNode = root.GetSubTree(i) as DefunTreeNode;
-          if (otherDefunNode != null) {
-            GrammarModifier.AddDynamicSymbol(newTree.Grammar, newTree.Symbol, otherDefunNode.FunctionName, otherDefunNode.NumberOfArguments);
-          }
-        }
-      }
-      if (newTree.Symbol is Defun) {
-        var defunTree = newTree as DefunTreeNode;
-        string formatString = new StringBuilder().Append('0', (int)Math.Log10(maxFunctionDefinitions * 10 - 1)).ToString(); // >= 100 functions => ###
-        var allowedNames = from index in Enumerable.Range(0, maxFunctionDefinitions)
-                           select "ADF" + index.ToString(formatString);
-        var takenNames = (from node in root.IterateNodesPrefix().OfType<DefunTreeNode>()
-                          select node.FunctionName).Distinct();
-        var remainingNames = allowedNames.Except(takenNames).ToList();
-        string functionName = remainingNames[random.Next(remainingNames.Count)];
-        // set name and number of arguments of the ADF
-        int nArgs = random.Next(maxFunctionArguments);
-        defunTree.FunctionName = functionName;
-        defunTree.NumberOfArguments = nArgs;
-        if (nArgs > 0) {
-          GrammarModifier.AddDynamicArguments(defunTree.Grammar, defunTree.Symbol, Enumerable.Range(0, nArgs));
-        }
-        // in existing branches with smaller index allow invoke of current function
-        int argIndex = root.IndexOfSubTree(newTree);
-        for (int i = 0; i < argIndex; i++) {
-          // if not dummy node
-          if (root.GetSubTree(i).Symbol != null) {
-            var existingBranch = root.GetSubTree(i);
-            GrammarModifier.AddDynamicSymbol(existingBranch.Grammar, existingBranch.Symbol, functionName, nArgs);
-          }
-        }
+        ReplaceWithMinimalTree(random, root, tree, i);
       }
     }
@@ -285,6 +234,6 @@
     private static int SampleArity(IRandom random, ISymbolicExpressionTreeNode node, int targetLength) {
       // select actualArity randomly with the constraint that the sub-trees in the minimal arity can become large enough
-      int minArity = node.Grammar.GetMinSubtreeCount(node.Symbol);
-      int maxArity = node.Grammar.GetMaxSubtreeCount(node.Symbol);
+      int minArity = node.Grammar.GetMinimumSubtreeCount(node.Symbol);
+      int maxArity = node.Grammar.GetMaximumSubtreeCount(node.Symbol);
       if (maxArity > targetLength) {
         maxArity = targetLength;
@@ -294,6 +243,6 @@
       long aggregatedLongestExpressionLength = 0;
       for (int i = 0; i < maxArity; i++) {
-        aggregatedLongestExpressionLength += (from s in node.Grammar.GetAllowedSymbols(node.Symbol, i)
-                                              select node.Grammar.GetMaxExpressionLength(s)).Max();
+        aggregatedLongestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i)
+                                              select node.Grammar.GetMaximumExpressionLength(s)).Max();
         if (aggregatedLongestExpressionLength < targetLength) minArity = i;
         else break;
@@ -304,6 +253,6 @@
       long aggregatedShortestExpressionLength = 0;
       for (int i = 0; i < maxArity; i++) {
-        aggregatedShortestExpressionLength += (from s in node.Grammar.GetAllowedSymbols(node.Symbol, i)
-                                               select node.Grammar.GetMinExpressionLength(s)).Min();
+        aggregatedShortestExpressionLength += (from s in node.Grammar.GetAllowedChildSymbols(node.Symbol, i)
+                                               select node.Grammar.GetMinimumExpressionLength(s)).Min();
         if (aggregatedShortestExpressionLength > targetLength) {
           maxArity = i;
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/CrossoverPoint.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/CrossoverPoint.cs	(revision 5685)
+++ 	(revision )
@@ -1,35 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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
-
-
-namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  internal class CrossoverPoint {
-    public ISymbolicExpressionTreeNode Parent { get; set; }
-    public ISymbolicExpressionTreeNode Child { get; set; }
-    public int SubtreeIndex {
-      get { return Parent.IndexOfSubTree(Child); }
-    }
-    public CrossoverPoint(ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode child) {
-      this.Parent = parent;
-      this.Child = child;
-    }
-  }
-}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs	(revision 5686)
@@ -120,5 +120,5 @@
       // check syntax constraints of direct parent - child relation
       if (!parent.Grammar.ContainsSymbol(branch.Symbol) ||
-          !parent.Grammar.IsAllowedChild(parent.Symbol, branch.Symbol, replacedSubtreeIndex)) return false;
+          !parent.Grammar.IsAllowedChildSymbol(parent.Symbol, branch.Symbol, replacedSubtreeIndex)) return false;
 
       bool result = true;
@@ -128,6 +128,6 @@
           result &&
           parent.Grammar.ContainsSymbol(n.Symbol) &&
-          n.SubTrees.Count() >= parent.Grammar.GetMinSubtreeCount(n.Symbol) &&
-          n.SubTrees.Count() <= parent.Grammar.GetMaxSubtreeCount(n.Symbol);
+          n.SubtreesCount >= parent.Grammar.GetMinimumSubtreeCount(n.Symbol) &&
+          n.SubtreesCount <= parent.Grammar.GetMaximumSubtreeCount(n.Symbol);
       });
       return result;
@@ -136,15 +136,15 @@
     private static void SelectCrossoverPoint(IRandom random, ISymbolicExpressionTree parent0, double internalNodeProbability, int maxBranchLength, int maxBranchDepth, out ISymbolicExpressionTreeNode crossoverPoint, out int subtreeIndex) {
       if (internalNodeProbability < 0.0 || internalNodeProbability > 1.0) throw new ArgumentException("internalNodeProbability");
-      List<CrossoverPoint> internalCrossoverPoints = new List<CrossoverPoint>();
-      List<CrossoverPoint> leafCrossoverPoints = new List<CrossoverPoint>();
+      List<CutPoint> internalCrossoverPoints = new List<CutPoint>();
+      List<CutPoint> leafCrossoverPoints = new List<CutPoint>();
       parent0.Root.ForEachNodePostfix((n) => {
-        if (n.SubTrees.Count() > 0 && n != parent0.Root) {
+        if (n.SubTrees.Any() && n != parent0.Root) {
           foreach (var child in n.SubTrees) {
             if (child.GetLength() <= maxBranchLength &&
                 child.GetDepth() <= maxBranchDepth) {
-              if (child.SubTrees.Count() > 0)
-                internalCrossoverPoints.Add(new CrossoverPoint(n, child));
+              if (child.SubTrees.Any())
+                internalCrossoverPoints.Add(new CutPoint(n, child));
               else
-                leafCrossoverPoints.Add(new CrossoverPoint(n, child));
+                leafCrossoverPoints.Add(new CutPoint(n, child));
             }
           }
@@ -158,10 +158,10 @@
           var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
           crossoverPoint = selectedCrossoverPoint.Parent;
-          subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+          subtreeIndex = selectedCrossoverPoint.ChildIndex;
         } else {
           // otherwise select external node
           var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
           crossoverPoint = selectedCrossoverPoint.Parent;
-          subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+          subtreeIndex = selectedCrossoverPoint.ChildIndex;
         }
       } else if (leafCrossoverPoints.Count > 0) {
@@ -169,10 +169,10 @@
         var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
         crossoverPoint = selectedCrossoverPoint.Parent;
-        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+        subtreeIndex = selectedCrossoverPoint.ChildIndex;
       } else {
         // otherwise select internal crossover point
         var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
         crossoverPoint = selectedCrossoverPoint.Parent;
-        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+        subtreeIndex = selectedCrossoverPoint.ChildIndex;
       }
     }
@@ -185,5 +185,5 @@
         // select internal node if possible
         allowedInternalBranches = (from branch in branches
-                                   where branch.SubTrees.Count() > 0
+                                   where branch.SubTrees.Any()
                                    select branch).ToList();
         if (allowedInternalBranches.Count > 0) {
@@ -192,5 +192,5 @@
           // no internal nodes allowed => select leaf nodes
           allowedLeafBranches = (from branch in branches
-                                 where branch.SubTrees.Count() == 0
+                                 where !branch.SubTrees.Any()
                                  select branch).ToList();
           return allowedLeafBranches.SelectRandom(random);
@@ -199,5 +199,5 @@
         // select leaf node if possible
         allowedLeafBranches = (from branch in branches
-                               where branch.SubTrees.Count() == 0
+                               where !branch.SubTrees.Any()
                                select branch).ToList();
         if (allowedLeafBranches.Count > 0) {
@@ -205,5 +205,5 @@
         } else {
           allowedInternalBranches = (from branch in branches
-                                     where branch.SubTrees.Count() > 0
+                                     where branch.SubTrees.Any()
                                      select branch).ToList();
           return allowedInternalBranches.SelectRandom(random);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs	(revision 5686)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/CutPoint.cs	(revision 5686)
@@ -0,0 +1,37 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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
+
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  internal class CutPoint {
+    public ISymbolicExpressionTreeNode Parent { get; set; }
+    public ISymbolicExpressionTreeNode Child { get; set; }
+    private int childIndex;
+    public int ChildIndex {
+      get { return childIndex; }
+    }
+    public CutPoint(ISymbolicExpressionTreeNode parent, ISymbolicExpressionTreeNode child) {
+      this.Parent = parent;
+      this.Child = child;
+      this.childIndex = parent.IndexOfSubTree(child);
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 5686)
@@ -124,9 +124,11 @@
     <Compile Include="Compiler\SymbolicExpressionTreeCompiler.cs" />
     <Compile Include="Interfaces\IReadOnlySymbol.cs" />
+    <Compile Include="Interfaces\ISymbolicExpressionGrammar.cs" />
+    <Compile Include="Interfaces\ISymbolicExpressionGrammarBase.cs" />
     <Compile Include="Interfaces\ISymbolicExpressionTreeGrammar.cs" />
     <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeArchitectureAlteringOperator.cs" />
     <Compile Include="Interfaces\Operators\ISymbolicExpressionTreeGrammarBasedOperator.cs" />
     <Compile Include="Creators\SymbolicExpressionTreeCreator.cs" />
-    <Compile Include="Crossovers\CrossoverPoint.cs" />
+    <Compile Include="CutPoint.cs" />
     <Compile Include="Crossovers\SymbolicExpressionTreeCrossover.cs" />
     <Compile Include="Formatters\SymbolicExpressionTreeStringFormatter.cs" />
@@ -147,4 +149,6 @@
     <Compile Include="Manipulators\OnePointShaker.cs" />
     <Compile Include="Manipulators\SymbolicExpressionTreeManipulator.cs" />
+    <Compile Include="SymbolicExpressionGrammarBase.cs" />
+    <Compile Include="SymbolicExpressionGrammar.cs" />
     <Compile Include="SymbolicExpressionTreeGrammar.cs" />
     <Compile Include="SymbolicExpressionTreeTopLevelNode.cs" />
@@ -152,9 +156,5 @@
       <SubType>Code</SubType>
     </Compile>
-    <Compile Include="GlobalSymbolicExpressionGrammar.cs" />
     <Compile Include="EnumerableExtensions.cs" />
-    <Compile Include="DefaultSymbolicExpressionGrammar.cs">
-      <SubType>Code</SubType>
-    </Compile>
     <Compile Include="SymbolicExpressionTreeOperator.cs" />
     <Compile Include="SymbolicExpressionTreeTerminalNode.cs" />
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs	(revision 5686)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs	(revision 5686)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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
+
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  public interface ISymbolicExpressionGrammar : ISymbolicExpressionGrammarBase {
+    ISymbol ProgramRootSymbol { get; }
+    ISymbol StartSymbol { get; }
+
+    int MinimumFunctionDefinitions { get; set; }
+    int MaximumFunctionDefinitions { get; set; }
+    int MinimumFunctionArguments { get; set; }
+    int MaximumFunctionArguments { get; set; }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammarBase.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammarBase.cs	(revision 5686)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammarBase.cs	(revision 5686)
@@ -0,0 +1,44 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  public interface ISymbolicExpressionGrammarBase : INamedItem {
+    IEnumerable<ISymbol> Symbols { get; }
+    ISymbol GetSymbol(string symbolName);
+    IEnumerable<ISymbol> AllowedSymbols { get; }
+    bool ContainsSymbol(ISymbol symbol);
+
+    bool IsAllowedChildSymbol(ISymbol parent, ISymbol child);
+    bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex);
+    IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent);
+    IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent, int argumentIndex);
+
+    int GetMinimumSubtreeCount(ISymbol symbol);
+    int GetMaximumSubtreeCount(ISymbol symbol);
+
+    int GetMinimumExpressionLength(ISymbol start);
+    int GetMaximumExpressionLength(ISymbol start);
+    int GetMinimumExpressionDepth(ISymbol start);
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeGrammar.cs	(revision 5686)
@@ -21,27 +21,18 @@
 
 using System.Collections.Generic;
-using HeuristicLab.Core;
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  public interface ISymbolicExpressionTreeGrammar : ISymbolicExpressionGrammarBase {
 
-namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  public interface ISymbolicExpressionTreeGrammar : IItem {
-    IEnumerable<ISymbol> Symbols { get; }
-    ISymbol StartSymbol { get; }
+    IEnumerable<ISymbol> ModifyableSymbols { get; }
+    bool IsModifyableSymbol(ISymbol symbol);
     void AddSymbol(ISymbol symbol);
     void RemoveSymbol(ISymbol symbol);
 
-    bool ContainsSymbol(ISymbol symbol);
-    void SetAllowedChild(ISymbol parent, ISymbol child, int argumentIndex);
-    bool IsAllowedChild(ISymbol parent, ISymbol child, int argumentIndex);
+    void AddAllowedChildSymbol(ISymbol parent, ISymbol child);
+    void AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex);
+    void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child);
+    void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex);
 
-    IEnumerable<ISymbol> GetAllowedSymbols(ISymbol parent, int argumentIndex);
-
-    int GetMinExpressionLength(ISymbol start);
-    int GetMaxExpressionLength(ISymbol start);
-    int GetMinExpressionDepth(ISymbol start);
-
-    int GetMinSubtreeCount(ISymbol symbol);
-    void SetMinSubtreeCount(ISymbol symbol, int value);
-    int GetMaxSubtreeCount(ISymbol symbol);
-    void SetMaxSubtreeCount(ISymbol symbol, int value);
+    void SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount);
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs	(revision 5686)
@@ -19,8 +19,8 @@
  */
 #endregion
+using System;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
-using System;
-using HeuristicLab.Common;
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   public interface ISymbolicExpressionTreeNode : IDeepCloneable {
@@ -39,4 +39,5 @@
 
     IEnumerable<ISymbolicExpressionTreeNode> SubTrees { get; }
+    int SubtreesCount { get; }
     ISymbolicExpressionTreeNode GetSubTree(int index);
     int IndexOfSubTree(ISymbolicExpressionTreeNode tree);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeGrammarBasedOperator.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeGrammarBasedOperator.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeGrammarBasedOperator.cs	(revision 5686)
@@ -27,5 +27,5 @@
   /// </summary>
   public interface ISymbolicExpressionTreeGrammarBasedOperator : ISymbolicExpressionTreeOperator {
-    IValueLookupParameter<ISymbolicExpressionTreeGrammar> SymbolicExpressionTreeGrammarParameter { get; }
+    IValueLookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionTreeGrammarParameter { get; }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ChangeNodeTypeManipulation.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ChangeNodeTypeManipulation.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ChangeNodeTypeManipulation.cs	(revision 5686)
@@ -20,10 +20,7 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
@@ -53,13 +50,13 @@
                                 let existingSubtreeCount = subtree.SubTrees.Count()
                                 // find possible symbols for the node (also considering the existing branches below it)
-                                let allowedSymbols = (from symbol in parent.Grammar.GetAllowedSymbols(parent.Symbol, subtreeIndex)
+                                let allowedSymbols = (from symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, subtreeIndex)
                                                       // do not replace the existing symbol with itself
                                                       where symbol.Name != subtree.Symbol.Name
-                                                      where existingSubtreeCount <= parent.Grammar.GetMaxSubtreeCount(symbol)
-                                                      where existingSubtreeCount >= parent.Grammar.GetMinSubtreeCount(symbol)
+                                                      where existingSubtreeCount <= parent.Grammar.GetMaximumSubtreeCount(symbol)
+                                                      where existingSubtreeCount >= parent.Grammar.GetMinimumSubtreeCount(symbol)
                                                       // keep only symbols that are still possible considering the existing sub-trees
                                                       where (from existingSubtreeIndex in Enumerable.Range(0, existingSubtreeCount)
                                                              let existingSubtree = subtree.GetSubTree(existingSubtreeIndex)
-                                                             select parent.Grammar.IsAllowedChild(symbol, existingSubtree.Symbol, existingSubtreeIndex))
+                                                             select parent.Grammar.IsAllowedChildSymbol(symbol, existingSubtree.Symbol, existingSubtreeIndex))
                                                              .All(x => x == true)
                                                       select symbol)
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ReplaceBranchManipulation.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ReplaceBranchManipulation.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Manipulators/ReplaceBranchManipulation.cs	(revision 5686)
@@ -20,12 +20,10 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Parameters;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
@@ -77,9 +75,9 @@
                                 let maxDepth = maxTreeDepth - symbolicExpressionTree.Depth + subtree.GetDepth()
                                 // find possible symbols for the node (also considering the existing branches below it)
-                                let allowedSymbols = (from symbol in parent.Grammar.GetAllowedSymbols(parent.Symbol, subtreeIndex)
+                                let allowedSymbols = (from symbol in parent.Grammar.GetAllowedChildSymbols(parent.Symbol, subtreeIndex)
                                                       // do not replace symbol with the same symbol
                                                       where symbol.Name != subtree.Symbol.Name
-                                                      where parent.Grammar.GetMinExpressionDepth(symbol) <= maxDepth
-                                                      where parent.Grammar.GetMinExpressionLength(symbol) <= maxLength
+                                                      where parent.Grammar.GetMinimumExpressionDepth(symbol) <= maxDepth
+                                                      where parent.Grammar.GetMinimumExpressionLength(symbol) <= maxLength
                                                       select symbol)
                                                       .ToList()
@@ -107,5 +105,5 @@
       selectedManipulationPoint.Parent.RemoveSubTree(selectedManipulationPoint.Index);
       selectedManipulationPoint.Parent.InsertSubTree(selectedManipulationPoint.Index, seedNode);
-      seedNode = ProbabilisticTreeCreator.PTC2(random, seedNode, selectedManipulationPoint.MaxLength, selectedManipulationPoint.MaxDepth, 0, 0);
+      ProbabilisticTreeCreator.PTC2(random, seedNode, selectedManipulationPoint.MaxLength, selectedManipulationPoint.MaxDepth);
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs	(revision 5686)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs	(revision 5686)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [StorableClass]
+  public abstract class SymbolicExpressionGrammar : SymbolicExpressionGrammarBase, ISymbolicExpressionGrammar {
+    #region fields & properties
+    [Storable]
+    private int minimumFunctionDefinitions;
+    public int MinimumFunctionDefinitions {
+      get { return minimumFunctionDefinitions; }
+      set {
+        minimumFunctionDefinitions = value;
+        UpdateAdfConstraints();
+      }
+    }
+    [Storable]
+    private int maximumFunctionDefinitions;
+    public int MaximumFunctionDefinitions {
+      get { return maximumFunctionDefinitions; }
+      set {
+        maximumFunctionDefinitions = value;
+        UpdateAdfConstraints();
+      }
+    }
+    [Storable]
+    private int minimumFunctionArguments;
+    public int MinimumFunctionArguments {
+      get { return minimumFunctionArguments; }
+      set {
+        minimumFunctionArguments = value;
+      }
+    }
+    [Storable]
+    private int maximumFunctionArguments;
+    public int MaximumFunctionArguments {
+      get { return maximumFunctionArguments; }
+      set {
+        maximumFunctionArguments = value;
+      }
+    }
+
+    [Storable]
+    private ProgramRootSymbol programRootSymbol;
+    public ProgramRootSymbol ProgramRootSymbol {
+      get { return programRootSymbol; }
+    }
+    ISymbol ISymbolicExpressionGrammar.ProgramRootSymbol {
+      get { return ProgramRootSymbol; }
+    }
+
+    [Storable]
+    private StartSymbol startSymbol;
+    public StartSymbol StartSymbol {
+      get { return startSymbol; }
+    }
+    ISymbol ISymbolicExpressionGrammar.StartSymbol {
+      get { return StartSymbol; }
+    }
+
+    [Storable]
+    private Defun defunSymbol;
+    protected Defun DefunSymbol {
+      get { return defunSymbol; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected SymbolicExpressionGrammar(bool deserializing) : base(deserializing) { }
+    protected SymbolicExpressionGrammar(SymbolicExpressionGrammar original, Cloner cloner)
+      : base(original, cloner) {
+      programRootSymbol = (ProgramRootSymbol)cloner.Clone(original.programRootSymbol);
+      startSymbol = (StartSymbol)cloner.Clone(original.StartSymbol);
+      defunSymbol = (Defun)cloner.Clone(original.defunSymbol);
+      maximumFunctionArguments = original.maximumFunctionArguments;
+      minimumFunctionArguments = original.minimumFunctionArguments;
+      maximumFunctionDefinitions = original.maximumFunctionDefinitions;
+      minimumFunctionDefinitions = original.minimumFunctionDefinitions;
+    }
+
+    public SymbolicExpressionGrammar()
+      : base() {
+      programRootSymbol = new ProgramRootSymbol();
+      AddSymbol(programRootSymbol);
+      startSymbol = new StartSymbol();
+      AddSymbol(startSymbol);
+      defunSymbol = new Defun();
+      AddSymbol(defunSymbol);
+
+      SetSubtreeCount(programRootSymbol, 1, 1);
+      AddAllowedChildSymbol(programRootSymbol, startSymbol, 0);
+      UpdateAdfConstraints();
+
+      SetSubtreeCount(defunSymbol, 1, 1);
+    }
+
+    private void UpdateAdfConstraints() {
+      SetSubtreeCount(programRootSymbol, minimumFunctionDefinitions + 1, maximumFunctionDefinitions + 1);
+
+      // ADF branches maxFunctionDefinitions 
+      for (int argumentIndex = 1; argumentIndex < maximumFunctionDefinitions + 1; argumentIndex++) {
+        AddAllowedChildSymbol(programRootSymbol, defunSymbol, argumentIndex);
+      }
+    }
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 5686)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 5686)
@@ -0,0 +1,275 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  /// <summary>
+  /// The default symbolic expression grammar stores symbols and syntactic constraints for symbols.
+  /// Symbols are treated as equvivalent if they have the same name.
+  /// Syntactic constraints limit the number of allowed sub trees for a node with a symbol and which symbols are allowed 
+  /// in the sub-trees of a symbol (can be specified for each sub-tree index separately).
+  /// </summary>
+  [StorableClass]
+  public abstract class SymbolicExpressionGrammarBase : NamedItem, ISymbolicExpressionGrammarBase {
+    #region properties for separation between implementation and persistence
+
+    //TODO implement storable properties;
+
+    #endregion
+
+    protected Dictionary<string, ISymbol> symbols;
+    protected Dictionary<string, Tuple<int, int>> symbolSubTreeCount;
+    protected Dictionary<string, List<string>> allowedChildSymbols;
+    protected Dictionary<Tuple<string, int>, List<string>> allowedChildSymbolsPerIndex;
+
+    [StorableConstructor]
+    protected SymbolicExpressionGrammarBase(bool deserializing)
+      : base(deserializing) {
+      cachedMinExpressionLength = new Dictionary<string, int>();
+      cachedMaxExpressionLength = new Dictionary<string, int>();
+      cachedMinExpressionDepth = new Dictionary<string, int>();
+    }
+    protected SymbolicExpressionGrammarBase(SymbolicExpressionGrammarBase original, Cloner cloner)
+      : base(original, cloner) {
+      cachedMinExpressionLength = new Dictionary<string, int>();
+      cachedMaxExpressionLength = new Dictionary<string, int>();
+      cachedMinExpressionDepth = new Dictionary<string, int>();
+
+      symbolSubTreeCount = new Dictionary<string, Tuple<int, int>>(original.symbolSubTreeCount);
+      symbols = new Dictionary<string, ISymbol>(original.symbols);
+
+      allowedChildSymbols = new Dictionary<string, List<string>>();
+      foreach (var element in original.allowedChildSymbols)
+        allowedChildSymbols.Add(element.Key, new List<string>(element.Value));
+
+      allowedChildSymbolsPerIndex = new Dictionary<Tuple<string, int>, List<string>>();
+      foreach (var element in original.allowedChildSymbolsPerIndex)
+        allowedChildSymbolsPerIndex.Add(element.Key, new List<string>(element.Value));
+    }
+
+    protected SymbolicExpressionGrammarBase()
+      : base() {
+      cachedMinExpressionLength = new Dictionary<string, int>();
+      cachedMaxExpressionLength = new Dictionary<string, int>();
+      cachedMinExpressionDepth = new Dictionary<string, int>();
+
+      symbols = new Dictionary<string, ISymbol>();
+      symbolSubTreeCount = new Dictionary<string, Tuple<int, int>>();
+      allowedChildSymbols = new Dictionary<string, List<string>>();
+      allowedChildSymbolsPerIndex = new Dictionary<Tuple<string, int>, List<string>>();
+    }
+
+    #region protected grammar manipulation methods
+    protected void AddSymbol(ISymbol symbol) {
+      if (ContainsSymbol(symbol)) throw new ArgumentException("Symbol " + symbol + " is already defined.");
+      symbols.Add(symbol.Name, symbol);
+      symbolSubTreeCount.Add(symbol.Name, Tuple.Create(0, 0));
+      ClearCaches();
+    }
+
+    protected void RemoveSymbol(ISymbol symbol) {
+      symbols.Remove(symbol.Name);
+      allowedChildSymbols.Remove(symbol.Name);
+      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++)
+        allowedChildSymbolsPerIndex.Remove(Tuple.Create(symbol.Name, i));
+      symbolSubTreeCount.Remove(symbol.Name);
+
+
+      foreach (var parent in Symbols) {
+        List<string> allowedChilds;
+        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
+          allowedChilds.Remove(symbol.Name);
+
+        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
+          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
+            allowedChilds.Remove(symbol.Name);
+        }
+      }
+      ClearCaches();
+    }
+
+    public virtual ISymbol GetSymbol(string symbolName) {
+      ISymbol symbol;
+      if (symbols.TryGetValue(symbolName, out symbol)) return symbol;
+      return null;
+    }
+
+    protected void AddAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      List<string> childSymbols;
+      if (!allowedChildSymbols.TryGetValue(parent.Name, out childSymbols)) {
+        childSymbols = new List<string>();
+        allowedChildSymbols.Add(parent.Name, childSymbols);
+      }
+      childSymbols.Add(child.Name);
+      ClearCaches();
+    }
+
+    protected void AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      var key = Tuple.Create(parent.Name, argumentIndex);
+      List<string> childSymbols;
+      if (!allowedChildSymbolsPerIndex.TryGetValue(key, out childSymbols)) {
+        childSymbols = new List<string>();
+        allowedChildSymbolsPerIndex.Add(key, childSymbols);
+      }
+
+      childSymbols.Add(child.Name);
+      ClearCaches();
+    }
+
+    protected void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      allowedChildSymbols[parent.Name].Remove(child.Name);
+      ClearCaches();
+    }
+
+    protected void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      var key = Tuple.Create(parent.Name, argumentIndex);
+      allowedChildSymbolsPerIndex[key].Remove(child.Name);
+      ClearCaches();
+    }
+
+    protected void SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount) {
+      for (int i = GetMaximumSubtreeCount(symbol) - 1; i >= maximumSubtreeCount; i--) {
+        var key = Tuple.Create(symbol.Name, i);
+        allowedChildSymbolsPerIndex.Remove(key);
+      }
+
+      symbolSubTreeCount[symbol.Name] = Tuple.Create(minimumSubtreeCount, maximumSubtreeCount);
+      ClearCaches();
+    }
+    #endregion
+
+    #region ISymbolicExpressionGrammarBase Members
+    public virtual IEnumerable<ISymbol> Symbols {
+      get { return symbols.Values; }
+    }
+    public virtual IEnumerable<ISymbol> AllowedSymbols {
+      get { return Symbols.Where(s => !s.InitialFrequency.IsAlmost(0.0)); }
+    }
+    public virtual bool ContainsSymbol(ISymbol symbol) {
+      return symbols.ContainsKey(symbol.Name);
+    }
+
+    public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      List<string> temp;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out temp))
+        if (temp.Contains(child.Name)) return true;
+      return false;
+    }
+
+    public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      List<string> temp;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out temp))
+        if (temp.Contains(child.Name)) return true;
+
+      var key = Tuple.Create(parent.Name, argumentIndex);
+      if (allowedChildSymbolsPerIndex.TryGetValue(key, out temp))
+        return temp.Contains(child.Name);
+      return false;
+    }
+
+    public virtual IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent) {
+      return from s in Symbols where IsAllowedChildSymbol(parent, s) select s;
+    }
+
+    public virtual IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent, int argumentIndex) {
+      var result = Enumerable.Empty<string>();
+
+      List<string> temp;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out temp))
+        result = result.Union(temp);
+      var key = Tuple.Create(parent.Name, argumentIndex);
+      if (allowedChildSymbolsPerIndex.TryGetValue(key, out temp))
+        result = result.Union(temp);
+
+      return result.Select(x => GetSymbol(x));
+    }
+
+    public virtual int GetMinimumSubtreeCount(ISymbol symbol) {
+      return symbolSubTreeCount[symbol.Name].Item1;
+    }
+    public virtual int GetMaximumSubtreeCount(ISymbol symbol) {
+      return symbolSubTreeCount[symbol.Name].Item2;
+    }
+
+
+    private void ClearCaches() {
+      cachedMinExpressionLength.Clear();
+      cachedMaxExpressionLength.Clear();
+      cachedMinExpressionDepth.Clear();
+    }
+
+    private Dictionary<string, int> cachedMinExpressionLength;
+    public int GetMinimumExpressionLength(ISymbol symbol) {
+      int temp;
+      if (!cachedMinExpressionLength.TryGetValue(symbol.Name, out temp)) {
+        cachedMinExpressionLength[symbol.Name] = int.MaxValue; // prevent infinite recursion
+        long sumOfMinExpressionLengths = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
+                                              let minForSlot = (long)(from s in Symbols
+                                                                      where IsAllowedChildSymbol(symbol, s, argIndex)
+                                                                      select GetMinimumExpressionLength(s)).DefaultIfEmpty(0).Min()
+                                              select minForSlot).DefaultIfEmpty(0).Sum();
+
+        cachedMinExpressionLength[symbol.Name] = (int)Math.Min(sumOfMinExpressionLengths, int.MaxValue);
+        return cachedMinExpressionLength[symbol.Name];
+      }
+      return temp;
+    }
+
+    private Dictionary<string, int> cachedMaxExpressionLength;
+    public int GetMaximumExpressionLength(ISymbol symbol) {
+      int temp;
+      if (!cachedMaxExpressionLength.TryGetValue(symbol.Name, out temp)) {
+        cachedMaxExpressionLength[symbol.Name] = int.MaxValue; // prevent infinite recursion
+        long sumOfMaxTrees = 1 + (from argIndex in Enumerable.Range(0, GetMaximumSubtreeCount(symbol))
+                                  let maxForSlot = (long)(from s in Symbols
+                                                          where IsAllowedChildSymbol(symbol, s, argIndex)
+                                                          select GetMaximumExpressionLength(s)).DefaultIfEmpty(0).Max()
+                                  select maxForSlot).DefaultIfEmpty(0).Sum();
+        long limit = int.MaxValue;
+        cachedMaxExpressionLength[symbol.Name] = (int)Math.Min(sumOfMaxTrees, limit);
+        return cachedMaxExpressionLength[symbol.Name];
+      }
+      return temp;
+    }
+
+    private Dictionary<string, int> cachedMinExpressionDepth;
+    public int GetMinimumExpressionDepth(ISymbol symbol) {
+      int temp;
+      if (!cachedMinExpressionDepth.TryGetValue(symbol.Name, out temp)) {
+        cachedMinExpressionDepth[symbol.Name] = int.MaxValue; // prevent infinite recursion
+        cachedMinExpressionDepth[symbol.Name] = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
+                                                     let minForSlot = (from s in Symbols
+                                                                       where IsAllowedChildSymbol(symbol, s, argIndex)
+                                                                       select GetMinimumExpressionDepth(s)).DefaultIfEmpty(0).Min()
+                                                     select minForSlot).DefaultIfEmpty(0).Max();
+        return cachedMinExpressionDepth[symbol.Name];
+      }
+      return temp;
+    }
+    #endregion
+  }
+}
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeGrammar.cs	(revision 5686)
@@ -20,26 +20,100 @@
 #endregion
 
+using System;
+using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  public sealed class SymbolicExpressionTreeGrammar : DefaultSymbolicExpressionGrammar {
-    public SymbolicExpressionTreeGrammar(ISymbolicExpressionTreeGrammar grammar)
-      : base(grammar) {
-    }
+  [StorableClass]
+  internal sealed class SymbolicExpressionTreeGrammar : SymbolicExpressionGrammarBase, ISymbolicExpressionTreeGrammar {
     [StorableConstructor]
     private SymbolicExpressionTreeGrammar(bool deserializing) : base(deserializing) { }
-    // don't call storable ctor of base class to prevent full cloning
-    // instead use storable ctor to initialize an empty grammar and fill with InizializeShallowClone
     private SymbolicExpressionTreeGrammar(SymbolicExpressionTreeGrammar original, Cloner cloner)
-      : base(false) {
-      cloner.RegisterClonedObject(original, this);
-      InitializeShallowClone(original);
+      : base(original, cloner) {
+      this.grammar = original.grammar;
     }
-    private SymbolicExpressionTreeGrammar() : base() { }
-
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicExpressionTreeGrammar(this, cloner);
     }
+
+    private ISymbolicExpressionGrammar grammar;
+    public SymbolicExpressionTreeGrammar(ISymbolicExpressionGrammar grammar)
+      : base() {
+      if (grammar == null) throw new ArgumentNullException();
+      this.grammar = grammar;
+    }
+
+    public override IEnumerable<ISymbol> Symbols {
+      get { return grammar.Symbols.Union(base.Symbols); }
+    }
+    public override IEnumerable<ISymbol> AllowedSymbols {
+      get { return base.AllowedSymbols; }
+    }
+    public IEnumerable<ISymbol> ModifyableSymbols {
+      get { return base.symbols.Values; }
+    }
+    public bool IsModifyableSymbol(ISymbol symbol) {
+      return base.symbols.ContainsKey(symbol.Name);
+    }
+
+    public override bool ContainsSymbol(ISymbol symbol) {
+      return grammar.ContainsSymbol(symbol) || base.ContainsSymbol(symbol);
+    }
+    public override ISymbol GetSymbol(string symbolName) {
+      var symbol = grammar.GetSymbol(symbolName);
+      if (symbol != null) return symbol;
+      symbol = base.GetSymbol(symbolName);
+      if (symbol != null) return symbol;
+      throw new ArgumentException();
+    }
+
+    public override bool IsAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      return grammar.IsAllowedChildSymbol(parent, child) || base.IsAllowedChildSymbol(parent, child);
+    }
+    public override bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      return grammar.IsAllowedChildSymbol(parent, child, argumentIndex) || base.IsAllowedChildSymbol(parent, child, argumentIndex);
+    }
+    public override IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent) {
+      return grammar.GetAllowedChildSymbols(parent).Union(base.GetAllowedChildSymbols(parent));
+    }
+    public override IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent, int argumentIndex) {
+      return grammar.GetAllowedChildSymbols(parent, argumentIndex).Union(base.GetAllowedChildSymbols(parent, argumentIndex));
+    }
+
+    public override int GetMinimumSubtreeCount(ISymbol symbol) {
+      if (grammar.ContainsSymbol(symbol)) return grammar.GetMinimumSubtreeCount(symbol);
+      return base.GetMinimumSubtreeCount(symbol);
+    }
+    public override int GetMaximumSubtreeCount(ISymbol symbol) {
+      if (grammar.ContainsSymbol(symbol)) return grammar.GetMaximumSubtreeCount(symbol);
+      return base.GetMaximumSubtreeCount(symbol);
+    }
+
+    void ISymbolicExpressionTreeGrammar.AddSymbol(ISymbol symbol) {
+      base.AddSymbol(symbol);
+    }
+    void ISymbolicExpressionTreeGrammar.RemoveSymbol(ISymbol symbol) {
+      if (!IsModifyableSymbol(symbol)) throw new InvalidOperationException();
+      base.RemoveSymbol(symbol);
+    }
+    void ISymbolicExpressionTreeGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      base.AddAllowedChildSymbol(parent, child);
+    }
+    void ISymbolicExpressionTreeGrammar.AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      base.AddAllowedChildSymbol(parent, child, argumentIndex);
+    }
+    void ISymbolicExpressionTreeGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      base.RemoveAllowedChildSymbol(parent, child);
+    }
+    void ISymbolicExpressionTreeGrammar.RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      base.RemoveAllowedChildSymbol(parent, child, argumentIndex);
+    }
+
+    void ISymbolicExpressionTreeGrammar.SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount) {
+      if (!IsModifyableSymbol(symbol)) throw new InvalidOperationException();
+      base.SetSubtreeCount(symbol, minimumSubtreeCount, maximumSubtreeCount);
+    }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 5686)
@@ -22,5 +22,4 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -126,4 +125,11 @@
     public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
 
+    public int SubtreesCount {
+      get {
+        if (subTrees == null) return 0;
+        return subTrees.Count;
+      }
+    }
+
     public virtual ISymbolicExpressionTreeNode GetSubTree(int index) {
       return subTrees[index];
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeTerminalNode.cs	(revision 5686)
@@ -22,7 +22,7 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System.Linq;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/AllArchitectureAlteringOperatorsTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/AllArchitectureAlteringOperatorsTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/AllArchitectureAlteringOperatorsTest.cs	(revision 5686)
@@ -56,4 +56,5 @@
       var grammar = Grammars.CreateArithmeticAndAdfGrammar();
       var random = new MersenneTwister(31415);
+      SymbolicExpressionTreeStringFormatter formatter = new SymbolicExpressionTreeStringFormatter();
       IntValue maxTreeSize = new IntValue(MAX_TREE_LENGTH);
       IntValue maxTreeHeigth = new IntValue(MAX_TREE_DEPTH);
@@ -61,10 +62,9 @@
       IntValue maxArgs = new IntValue(3);
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
         Util.IsValid(tree);
         trees.Add(tree);
       }
       Stopwatch stopwatch = new Stopwatch();
-      stopwatch.Start();
       int failedEvents = 0;
       for (int g = 0; g < N_ITERATIONS; g++) {
@@ -72,7 +72,11 @@
           if (random.NextDouble() < 0.5) {
             // manipulate
+            stopwatch.Start();
             var selectedTree = (ISymbolicExpressionTree)trees.SelectRandom(random).Clone();
+            var oldTree = (ISymbolicExpressionTree)selectedTree.Clone();
+            var oldFormatedTree = formatter.Format(oldTree);
             bool success = false;
-            switch (random.Next(6)) {
+            int sw = random.Next(6);
+            switch (sw) {
               case 0: success = ArgumentCreater.CreateNewArgument(random, selectedTree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3); break;
               case 1: success = ArgumentDeleter.DeleteArgument(random, selectedTree, 3, 3); break;
@@ -82,5 +86,7 @@
               case 5: success = SubroutineDeleter.DeleteSubroutine(random, selectedTree, 3, 3); break;
             }
+            stopwatch.Stop();
             if (!success) failedEvents++;
+            var newFormatedTree = formatter.Format(selectedTree);
             Util.IsValid(selectedTree);
             newTrees.Add(selectedTree);
@@ -98,5 +104,4 @@
         trees = newTrees;
       }
-      stopwatch.Stop();
       var msPerOperation = stopwatch.ElapsedMilliseconds / (double)POPULATION_SIZE / (double)N_ITERATIONS;
       Console.WriteLine("AllArchitectureAlteringOperators: " + Environment.NewLine +
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentCreaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentCreaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentCreaterTest.cs	(revision 5686)
@@ -21,6 +21,6 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
-using System.Collections.Generic;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Random;
@@ -57,5 +57,6 @@
         ISymbolicExpressionTree tree;
         do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+          SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
         } while (!TreeHasAdfWithParameter(tree, 3));
         var success = ArgumentCreater.CreateNewArgument(random, tree, 60000, 100, 3, 3);
@@ -66,5 +67,5 @@
       // difficult to make sure that create argument operations succeed because trees are macro-expanded can potentially become very big 
       // => just test if only a small proportion fails
-      Assert.IsTrue(failedOps < POPULATION_SIZE * 0.01 ); // only 1% may fail
+      Assert.IsTrue(failedOps < POPULATION_SIZE * 0.01); // only 1% may fail
       Console.WriteLine("ArgumentCreator: " + Environment.NewLine +
         "Failed operations: " + failedOps * 100.0 / POPULATION_SIZE + " %" + Environment.NewLine +
@@ -77,7 +78,7 @@
 
     private bool TreeHasAdfWithParameter(ISymbolicExpressionTree tree, int maxParameters) {
-      if(tree.Root.SubTrees.Count() != 2 ) return false;
+      if (tree.Root.SubTrees.Count() != 2) return false;
       var firstAdf = tree.Root.GetSubTree(1);
-      return firstAdf.Grammar.GetAllowedSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() < maxParameters;
+      return firstAdf.Grammar.GetAllowedChildSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() < maxParameters;
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDeleterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDeleterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDeleterTest.cs	(revision 5686)
@@ -56,5 +56,6 @@
         ISymbolicExpressionTree tree = null;
         do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+          SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
         } while (!TreeHasAdfWithArguments(tree));
         var success = ArgumentDeleter.DeleteArgument(random, tree, 3, 3);
@@ -73,5 +74,5 @@
       if (tree.Root.SubTrees.Count() != 2) return false;
       var firstAdf = tree.Root.GetSubTree(1);
-      return firstAdf.Grammar.GetAllowedSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() >= 2;
+      return firstAdf.Grammar.GetAllowedChildSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() >= 2;
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDuplicaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDuplicaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ArgumentDuplicaterTest.cs	(revision 5686)
@@ -21,6 +21,6 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
-using System.Collections.Generic;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Random;
@@ -56,6 +56,7 @@
         ISymbolicExpressionTree tree = null;
         do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
-        } while(!HasAdfWithArguments(tree));
+          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+          SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+        } while (!HasAdfWithArguments(tree));
         var success = ArgumentDuplicater.DuplicateArgument(random, tree, 3, 3);
         Assert.IsTrue(success);
@@ -74,5 +75,5 @@
       if (tree.Root.SubTrees.Count() != 2) return false;
       var firstAdf = tree.Root.GetSubTree(1);
-      return firstAdf.Grammar.GetAllowedSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() == 1;
+      return firstAdf.Grammar.GetAllowedChildSymbols(firstAdf.Symbol, 0).Where(x => x is Argument).Count() == 1;
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ChangeNodeTypeManipulationTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ChangeNodeTypeManipulationTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ChangeNodeTypeManipulationTest.cs	(revision 5686)
@@ -55,5 +55,5 @@
       int failedEvents = 0;
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
         string originalTree = formatter.Format(tree);
         ChangeNodeTypeManipulation.ChangeNodeType(random, tree);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs	(revision 5686)
@@ -94,5 +94,5 @@
     }
 
-    private class SimpleArithmeticGrammar : DefaultSymbolicExpressionGrammar {
+    private class SimpleArithmeticGrammar : SymbolicExpressionGrammar {
       protected SimpleArithmeticGrammar(SimpleArithmeticGrammar original, Cloner cloner) : base(original, cloner) { }
       public SimpleArithmeticGrammar()
@@ -119,40 +119,39 @@
 
         foreach (var funSymb in functionSymbols) {
-          SetMinSubtreeCount(funSymb, 1);
-          SetMaxSubtreeCount(funSymb, 3);
+          SetSubtreeCount(funSymb, 1, 3);
         }
-        SetMinSubtreeCount(terminal, 0);
-        SetMaxSubtreeCount(terminal, 0);
+        SetSubtreeCount(terminal, 0, 0);
 
+        SetSubtreeCount(StartSymbol, 1, 1);
         // allow each symbol as child of the start symbol
         foreach (var symb in allSymbols) {
-          SetAllowedChild(StartSymbol, symb, 0);
+          AddAllowedChildSymbol(StartSymbol, symb);
+          AddAllowedChildSymbol(DefunSymbol, symb);
         }
 
         // allow each symbol as child of every other symbol (except for terminals that have maxSubtreeCount == 0)
-        foreach (var parent in allSymbols) {
-          for (int i = 0; i < GetMaxSubtreeCount(parent); i++)
-            foreach (var child in allSymbols) {
-              SetAllowedChild(parent, child, i);
-            }
+        foreach (var parent in functionSymbols) {
+          foreach (var child in allSymbols) {
+            AddAllowedChildSymbol(parent, child);
+          }
         }
       }
     }
 
-    public static ISymbolicExpressionTreeGrammar CreateSimpleArithmeticGrammar() {
-      var g = new GlobalSymbolicExpressionGrammar(new SimpleArithmeticGrammar());
-      g.MaxFunctionArguments = 0;
-      g.MinFunctionArguments = 0;
-      g.MaxFunctionDefinitions = 0;
-      g.MinFunctionDefinitions = 0;
+    public static ISymbolicExpressionGrammar CreateSimpleArithmeticGrammar() {
+      var g = new SimpleArithmeticGrammar();
+      g.MaximumFunctionArguments = 0;
+      g.MinimumFunctionArguments = 0;
+      g.MaximumFunctionDefinitions = 0;
+      g.MinimumFunctionDefinitions = 0;
       return g;
     }
 
-    public static ISymbolicExpressionTreeGrammar CreateArithmeticAndAdfGrammar() {
-      var g = new GlobalSymbolicExpressionGrammar(new SimpleArithmeticGrammar());
-      g.MaxFunctionArguments = 3;
-      g.MinFunctionArguments = 0;
-      g.MaxFunctionDefinitions = 3;
-      g.MinFunctionDefinitions = 0;
+    public static ISymbolicExpressionGrammar CreateArithmeticAndAdfGrammar() {
+      var g = new SimpleArithmeticGrammar();
+      g.MaximumFunctionArguments = 3;
+      g.MinimumFunctionArguments = 0;
+      g.MaximumFunctionDefinitions = 3;
+      g.MinimumFunctionDefinitions = 0;
       return g;
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ProbabilisticTreeCreaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ProbabilisticTreeCreaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ProbabilisticTreeCreaterTest.cs	(revision 5686)
@@ -22,8 +22,8 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Random;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Diagnostics;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding_3._4.Tests {
@@ -56,5 +56,5 @@
       stopwatch.Start();
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        randomTrees.Add(ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 0, 0));
+        randomTrees.Add(ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH));
       }
       stopwatch.Stop();
@@ -72,34 +72,5 @@
         Util.GetTerminalDistributionString(randomTrees) + Environment.NewLine
         );
-      Assert.IsTrue(Math.Round(1000.0 / (msPerRandomTreeCreation)) > 2000); // must achieve more than 2000 random trees / s
-    }
-
-
-    [TestMethod()]
-    public void ProbabilisticTreeCreaterWithAdfDistributionsTest() {
-      var randomTrees = new List<ISymbolicExpressionTree>();
-      var grammar = Grammars.CreateArithmeticAndAdfGrammar();
-      var random = new MersenneTwister(31415);
-      var stopwatch = new Stopwatch();
-      stopwatch.Start();
-      for (int i = 0; i < POPULATION_SIZE; i++) {
-        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
-        randomTrees.Add(tree);
-      }
-      stopwatch.Stop();
-      foreach (var tree in randomTrees)
-        Util.IsValid(tree);
-
-      double msPerRandomTreeCreation = stopwatch.ElapsedMilliseconds / (double)POPULATION_SIZE;
-
-      Console.WriteLine("ProbabilisticTreeCreator: " + Environment.NewLine +
-        msPerRandomTreeCreation + " ms per random tree (~" + Math.Round(1000.0 / (msPerRandomTreeCreation)) + "random trees / s)" + Environment.NewLine +
-        Util.GetSizeDistributionString(randomTrees, 105, 5) + Environment.NewLine +
-        Util.GetFunctionDistributionString(randomTrees) + Environment.NewLine +
-        Util.GetNumberOfSubTreesDistributionString(randomTrees) + Environment.NewLine +
-        Util.GetTerminalDistributionString(randomTrees) + Environment.NewLine
-        );
-
-      Assert.IsTrue(Math.Round(1000.0 / (msPerRandomTreeCreation)) > 2000); // must achieve more than 2000 random trees / s
+      Assert.IsTrue(Math.Round(1000.0 / (msPerRandomTreeCreation)) > 500); // must achieve more than 500 random trees / s
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ReplaceBranchManipulationTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ReplaceBranchManipulationTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/ReplaceBranchManipulationTest.cs	(revision 5686)
@@ -54,5 +54,6 @@
       var random = new MersenneTwister(31415);
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+        var tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+        SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
         string originalTree = formatter.Format(tree);
         ReplaceBranchManipulation.ReplaceRandomBranch(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineCreaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineCreaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineCreaterTest.cs	(revision 5686)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Linq;
 using System.Collections.Generic;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -55,7 +54,5 @@
       for (int i = 0; i < POPULATION_SIZE; i++) {
         ISymbolicExpressionTree tree = null;
-        do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
-        } while ( !OneMoreAdfAllowed(tree));
+        tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH - 10, MAX_TREE_DEPTH);
         var success = SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
         Assert.IsTrue(success);
@@ -70,8 +67,4 @@
         );
     }
-
-    private bool OneMoreAdfAllowed(ISymbolicExpressionTree tree) {
-      return tree.Length < 80 && tree.Root.SubTrees.Count() < 4;
-    }
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDeleterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDeleterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDeleterTest.cs	(revision 5686)
@@ -21,6 +21,6 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
-using System.Collections.Generic;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Random;
@@ -56,5 +56,7 @@
         ISymbolicExpressionTree tree = null;
         do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+          SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+          SubroutineCreater.CreateSubroutine(random, tree, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
         } while (!HasAtLeastOneAdf(tree));
         var success = SubroutineDeleter.DeleteSubroutine(random, tree, 3, 3);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDuplicaterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDuplicaterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubroutineDuplicaterTest.cs	(revision 5686)
@@ -21,6 +21,6 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
-using System.Collections.Generic;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 using HeuristicLab.Random;
@@ -56,5 +56,7 @@
         ISymbolicExpressionTree tree = null;
         do {
-          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH, 3, 3);
+          tree = ProbabilisticTreeCreator.Create(random, grammar, MAX_TREE_LENGTH, MAX_TREE_DEPTH);
+          for (int j = random.Next(3); j < 3; j++)
+            SubroutineCreater.CreateSubroutine(random, tree, 100, 10, 3, 3);
         } while (!HasOneAdf(tree));
         var success = SubroutineDuplicater.DuplicateSubroutine(random, tree, 3, 3);
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubtreeCrossoverTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubtreeCrossoverTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/SubtreeCrossoverTest.cs	(revision 5686)
@@ -56,5 +56,7 @@
 
       for (int i = 0; i < POPULATION_SIZE; i++) {
-        trees.Add(ProbabilisticTreeCreator.Create(random, grammar, 100, 10, 3, 3));
+        trees.Add(ProbabilisticTreeCreator.Create(random, grammar, 100, 10));
+        for (int j = random.Next(3); j < 3; j++)
+          SubroutineCreater.CreateSubroutine(random, trees[i], 100, 10, 3, 3);
       }
       Stopwatch stopwatch = new Stopwatch();
@@ -83,5 +85,5 @@
         );
 
-      Assert.IsTrue(Math.Round(1000.0 / (msPerCrossoverEvent)) > 2000); // must achieve more than 2000 x-overs/s
+      Assert.IsTrue(Math.Round(1000.0 / (msPerCrossoverEvent)) > 2500); // must achieve more than 1500 x-overs/s
     }
   }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs	(revision 5686)
@@ -120,16 +120,43 @@
       foreach (var defunTreeNode in tree.Root.SubTrees.OfType<DefunTreeNode>()) {
         int arity = defunTreeNode.NumberOfArguments;
+
+        foreach (var argTreenode in defunTreeNode.IterateNodesPrefix().OfType<ArgumentTreeNode>()) {
+          Assert.IsTrue(argTreenode.SubtreesCount == 0);
+          Assert.IsTrue(((Argument)argTreenode.Symbol).ArgumentIndex < arity);
+        }
+
+        foreach (var argSymbol in Enumerable.Range(0, defunTreeNode.NumberOfArguments).Select(x => new Argument(x))) {
+          Assert.IsTrue(defunTreeNode.Grammar.ContainsSymbol(argSymbol));
+          Assert.IsTrue(defunTreeNode.Grammar.GetMaximumSubtreeCount(argSymbol) == 0);
+          Assert.IsTrue(defunTreeNode.Grammar.GetMinimumSubtreeCount(argSymbol) == 0);
+        }
+
         var invoke = new InvokeFunction(defunTreeNode.FunctionName);
         foreach (var otherRootNode in tree.Root.SubTrees) {
           if (otherRootNode.Grammar.ContainsSymbol(invoke)) {
-            Assert.IsTrue(otherRootNode.Grammar.GetMinSubtreeCount(invoke) == arity);
-            Assert.IsTrue(otherRootNode.Grammar.GetMaxSubtreeCount(invoke) == arity);
+            Assert.IsTrue(otherRootNode.Grammar.GetMinimumSubtreeCount(invoke) == arity);
+            Assert.IsTrue(otherRootNode.Grammar.GetMaximumSubtreeCount(invoke) == arity);
           }
         }
+
       }
-      //Assert.AreEqual(tree.Root.Symbol, tree.Root.Grammar.StartSymbol);
-      foreach (var subtree in tree.Root.SubTrees)
+      foreach (var subtree in tree.Root.SubTrees) {
         Assert.AreNotSame(subtree.Grammar, tree.Root.Grammar);
+        IsValid(subtree.Grammar);
+      }
+
+      IsValid(tree.Root.Grammar);
       IsValid(tree.Root);
+    }
+
+    public static void IsValid(ISymbolicExpressionTreeGrammar grammar) {
+      Assert.IsTrue(grammar.Symbols.Count() == grammar.Symbols.Distinct().Count());
+      foreach (ISymbol symbol in grammar.Symbols) {
+        Assert.IsTrue(grammar.GetMinimumSubtreeCount(symbol) <= grammar.GetMaximumExpressionLength(symbol));
+        Assert.IsTrue(grammar.GetAllowedChildSymbols(symbol).Count() == grammar.GetAllowedChildSymbols(symbol).Distinct().Count());
+        for (int i = 0; i < grammar.GetMaximumSubtreeCount(symbol); i++) {
+          Assert.IsTrue(grammar.GetAllowedChildSymbols(symbol, i).Count() == grammar.GetAllowedChildSymbols(symbol, i).Distinct().Count());
+        }
+      }
     }
 
@@ -138,9 +165,9 @@
                             where symb.Name == treeNode.Symbol.Name
                             select symb).SingleOrDefault();
-      Assert.IsTrue(treeNode.SubTrees.Count() >= treeNode.Grammar.GetMinSubtreeCount(matchingSymbol));
-      Assert.IsTrue(treeNode.SubTrees.Count() <= treeNode.Grammar.GetMaxSubtreeCount(matchingSymbol));
+      Assert.IsTrue(treeNode.SubTrees.Count() >= treeNode.Grammar.GetMinimumSubtreeCount(matchingSymbol));
+      Assert.IsTrue(treeNode.SubTrees.Count() <= treeNode.Grammar.GetMaximumSubtreeCount(matchingSymbol));
       Assert.AreNotEqual(0.0, matchingSymbol.InitialFrequency); // check that no deactivated symbols occur in the tree
       for (int i = 0; i < treeNode.SubTrees.Count(); i++) {
-        Assert.IsTrue(treeNode.Grammar.GetAllowedSymbols(treeNode.Symbol, i).Select(x => x.Name).Contains(treeNode.GetSubTree(i).Symbol.Name));
+        Assert.IsTrue(treeNode.Grammar.GetAllowedChildSymbols(treeNode.Symbol, i).Select(x => x.Name).Contains(treeNode.GetSubTree(i).Symbol.Name));
         IsValid(treeNode.GetSubTree(i));
       }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntExpressionGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntExpressionGrammar.cs	(revision 5686)
@@ -28,5 +28,5 @@
 namespace HeuristicLab.Problems.ArtificialAnt {
   [StorableClass]
-  public class ArtificialAntExpressionGrammar : DefaultSymbolicExpressionGrammar {
+  public class ArtificialAntExpressionGrammar : SymbolicExpressionGrammar {
 
     public ArtificialAntExpressionGrammar()
@@ -53,26 +53,19 @@
 
       allSymbols.ForEach(s => AddSymbol(s));
-      SetMinSubtreeCount(ifFoodAhead, 2);
-      SetMaxSubtreeCount(ifFoodAhead, 2);
-      SetMinSubtreeCount(prog2, 2);
-      SetMaxSubtreeCount(prog2, 2);
-      SetMinSubtreeCount(prog3, 3);
-      SetMaxSubtreeCount(prog3, 3);
-      SetMinSubtreeCount(move, 0);
-      SetMaxSubtreeCount(move, 0);
-      SetMinSubtreeCount(left, 0);
-      SetMaxSubtreeCount(left, 0);
-      SetMinSubtreeCount(right, 0);
-      SetMaxSubtreeCount(right, 0);
+      SetSubtreeCount(ifFoodAhead, 2, 3);
+      SetSubtreeCount(prog2, 2, 2);
+      SetSubtreeCount(prog3, 3, 3);
+      SetSubtreeCount(move, 0, 0);
+      SetSubtreeCount(left, 0, 0);
+      SetSubtreeCount(right, 0, 0);
 
       // each symbols is allowed as child of the start symbol
-      allSymbols.ForEach(s => SetAllowedChild(StartSymbol, s, 0));
+      allSymbols.ForEach(s => AddAllowedChildSymbol(StartSymbol, s));
+      allSymbols.ForEach(s => AddAllowedChildSymbol(DefunSymbol, s));
 
       // each symbol is allowed as child of all other symbols (except for terminals that have MaxSubtreeCount == 0
-      foreach (var parent in allSymbols) {
-        for (int argIndex = 0; argIndex < GetMaxSubtreeCount(parent); argIndex++) {
-          foreach (var child in allSymbols) {
-            SetAllowedChild(parent, child, argIndex);
-          }
+      foreach (var parent in nonTerminalSymbols) {
+        foreach (var child in allSymbols) {
+          AddAllowedChildSymbol(parent, child);
         }
       }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntProblem.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntProblem.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.ArtificialAnt/3.4/ArtificialAntProblem.cs	(revision 5686)
@@ -101,6 +101,6 @@
       get { return EvaluatorParameter; }
     }
-    public IValueParameter<ISymbolicExpressionTreeGrammar> ArtificialAntExpressionGrammarParameter {
-      get { return (IValueParameter<ISymbolicExpressionTreeGrammar>)Parameters["ArtificialAntExpressionGrammar"]; }
+    public IValueParameter<ISymbolicExpressionGrammar> ArtificialAntExpressionGrammarParameter {
+      get { return (IValueParameter<ISymbolicExpressionGrammar>)Parameters["ArtificialAntExpressionGrammar"]; }
     }
     public IValueParameter<IntValue> MaxExpressionLengthParameter {
@@ -173,6 +173,6 @@
       get { return EvaluatorParameter.Value; }
     }
-    public GlobalSymbolicExpressionGrammar ArtificialAntExpressionGrammar {
-      get { return (GlobalSymbolicExpressionGrammar)ArtificialAntExpressionGrammarParameter.Value; }
+    public ArtificialAntExpressionGrammar ArtificialAntExpressionGrammar {
+      get { return (ArtificialAntExpressionGrammar)ArtificialAntExpressionGrammarParameter.Value; }
     }
     public DoubleValue BestKnownQuality {
@@ -211,5 +211,4 @@
       Evaluator evaluator = new Evaluator();
       BoolMatrix world = new BoolMatrix(santaFeAntTrail);
-      ISymbolicExpressionTreeGrammar grammar = new GlobalSymbolicExpressionGrammar(new ArtificialAntExpressionGrammar());
       Parameters.Add(new ValueParameter<BoolValue>("Maximization", "Set to true as the Artificial Ant Problem is a maximization problem.", new BoolValue(true)));
       Parameters.Add(new ValueParameter<ISymbolicExpressionTreeCreator>("SolutionCreator", "The operator which should be used to create new artificial ant solutions.", creator));
@@ -220,5 +219,5 @@
       Parameters.Add(new ValueParameter<IntValue>("MaxFunctionDefinitions", "Maximal number of automatically defined functions in the expression to control the artificial ant.", new IntValue(3)));
       Parameters.Add(new ValueParameter<IntValue>("MaxFunctionArguments", "Maximal number of arguments of automatically defined functions in the expression to control the artificial ant.", new IntValue(3)));
-      Parameters.Add(new ValueParameter<ISymbolicExpressionTreeGrammar>("ArtificialAntExpressionGrammar", "The grammar that should be used for artificial ant expressions.", grammar));
+      Parameters.Add(new ValueParameter<ISymbolicExpressionGrammar>("ArtificialAntExpressionGrammar", "The grammar that should be used for artificial ant expressions.", new ArtificialAntExpressionGrammar()));
       Parameters.Add(new ValueParameter<BoolMatrix>("World", "The world for the artificial ant with scattered food items.", world));
       Parameters.Add(new ValueParameter<IntValue>("MaxTimeSteps", "The number of time steps the artificial ant has available to collect all food items.", new IntValue(600)));
@@ -294,10 +293,10 @@
 
     private void MaxFunctionDefinitionsParameter_ValueChanged(object sender, EventArgs e) {
-      ArtificialAntExpressionGrammar.MaxFunctionDefinitions = MaxFunctionDefinitions.Value;
+      ArtificialAntExpressionGrammar.MaximumFunctionDefinitions = MaxFunctionDefinitions.Value;
       ParameterizeOperators();
       ParameterizeAnalyzers();
     }
     private void MaxFunctionArgumentsParameter_ValueChanged(object sender, EventArgs e) {
-      ArtificialAntExpressionGrammar.MaxFunctionArguments = MaxFunctionArguments.Value;
+      ArtificialAntExpressionGrammar.MaximumFunctionArguments = MaxFunctionArguments.Value;
       ParameterizeOperators();
       ParameterizeAnalyzers();
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/ArithmeticExpressionGrammar.cs	(revision 5686)
@@ -29,5 +29,5 @@
   [StorableClass]
   [Item("ArithmeticExpressionGrammar", "Represents a grammar for functional expressions using only arithmetic operations.")]
-  public class ArithmeticExpressionGrammar : DefaultSymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
+  public class ArithmeticExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
 
     [StorableConstructor]
@@ -59,23 +59,18 @@
 
       foreach (var funSymb in functionSymbols) {
-        SetMinSubtreeCount(funSymb, 1);
-        SetMaxSubtreeCount(funSymb, 3);
+        SetSubtreeCount(funSymb, 1, 3);
       }
-      SetMinSubtreeCount(constant, 0);
-      SetMaxSubtreeCount(constant, 0);
-      SetMinSubtreeCount(variableSymbol, 0);
-      SetMaxSubtreeCount(variableSymbol, 0);
+      SetSubtreeCount(constant, 0, 0);
+      SetSubtreeCount(variableSymbol, 0, 0);
 
       // allow each symbol as child of the start symbol
       foreach (var symb in allSymbols) {
-        SetAllowedChild(StartSymbol, symb, 0);
+        AddAllowedChildSymbol(StartSymbol, symb);
       }
 
       // allow each symbol as child of every other symbol (except for terminals that have maxSubtreeCount == 0)
-      foreach (var parent in allSymbols) {
-        for (int i = 0; i < GetMaxSubtreeCount(parent); i++)
-          foreach (var child in allSymbols) {
-            SetAllowedChild(parent, child, i);
-          }
+      foreach (var parent in functionSymbols) {
+        foreach (var child in allSymbols)
+          AddAllowedChildSymbol(parent, child);
       }
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/FullFunctionalExpressionGrammar.cs	(revision 5686)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -29,5 +30,5 @@
   [StorableClass]
   [Item("FullFunctionalExpressionGrammar", "Represents a grammar for functional expressions using all available functions.")]
-  public class FullFunctionalExpressionGrammar : DefaultSymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
+  public class FullFunctionalExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
     [StorableConstructor]
     protected FullFunctionalExpressionGrammar(bool deserializing) : base(deserializing) { }
@@ -92,36 +93,28 @@
 
       foreach (var funSymb in functionSymbols) {
-        SetMinSubtreeCount(funSymb, 1);
-        SetMaxSubtreeCount(funSymb, 3);
+        SetSubtreeCount(funSymb, 1, 3);
       }
       foreach (var funSymb in unaryFunctionSymbols) {
-        SetMinSubtreeCount(funSymb, 1);
-        SetMaxSubtreeCount(funSymb, 1);
+        SetSubtreeCount(funSymb, 1, 1);
       }
       foreach (var funSymb in binaryFunctionSymbols) {
-        SetMinSubtreeCount(funSymb, 2);
-        SetMaxSubtreeCount(funSymb, 2);
+        SetSubtreeCount(funSymb, 2, 2);
+      }
+      foreach (var terminalSymbol in terminalSymbols) {
+        SetSubtreeCount(terminalSymbol, 0, 0);
       }
 
-      foreach (var terminalSymbol in terminalSymbols) {
-        SetMinSubtreeCount(terminalSymbol, 0);
-        SetMaxSubtreeCount(terminalSymbol, 0);
-      }
-
-      SetMinSubtreeCount(@if, 3);
-      SetMaxSubtreeCount(@if, 3);
+      SetSubtreeCount(@if, 3, 3);
 
 
       // allow each symbol as child of the start symbol
       foreach (var symb in allSymbols) {
-        SetAllowedChild(StartSymbol, symb, 0);
+        AddAllowedChildSymbol(StartSymbol, symb);
       }
 
       // allow each symbol as child of every other symbol (except for terminals that have maxSubtreeCount == 0)
-      foreach (var parent in allSymbols) {
-        for (int i = 0; i < GetMaxSubtreeCount(parent); i++)
-          foreach (var child in allSymbols) {
-            SetAllowedChild(parent, child, i);
-          }
+      foreach (var parent in allSymbols.Except(terminalSymbols)) {
+        foreach (var child in allSymbols)
+          AddAllowedChildSymbol(parent, child);
       }
     }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Grammars/TypeCoherentExpressionGrammar.cs	(revision 5686)
@@ -29,5 +29,5 @@
   [StorableClass]
   [Item("TypeCoherentExpressionGrammar", "Represents a grammar for functional expressions in which special syntactic constraints are enforced so that boolean and real-valued expressions are not mixed.")]
-  public class TypeCoherentExpressionGrammar : DefaultSymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
+  public class TypeCoherentExpressionGrammar : SymbolicExpressionGrammar, ISymbolicDataAnalysisGrammar {
 
     [StorableConstructor]
@@ -123,29 +123,25 @@
 
       foreach (var unaryFun in unaryFunctionSymbols.Concat(unaryBooleanFunctionSymbols)) {
-        SetMinSubtreeCount(unaryFun, 1);
-        SetMaxSubtreeCount(unaryFun, 1);
+        SetSubtreeCount(unaryFun, 1, 1);
       }
       foreach (var binaryFun in binaryFunctionSymbols.Concat(binaryBooleanFunctionSymbols).Concat(relationalFunctionSymbols)) {
-        SetMinSubtreeCount(binaryFun, 2);
-        SetMaxSubtreeCount(binaryFun, 2);
+        SetSubtreeCount(binaryFun, 2, 2);
       }
 
       foreach (var terminalSymbol in terminalSymbols) {
-        SetMinSubtreeCount(terminalSymbol, 0);
-        SetMaxSubtreeCount(terminalSymbol, 0);
+        SetSubtreeCount(terminalSymbol, 0, 0);
       }
 
-      SetMinSubtreeCount(@if, 3);
-      SetMaxSubtreeCount(@if, 3);
+      SetSubtreeCount(@if, 3, 3);
 
 
       // allow only real-valued expressions as child of the start symbol
       foreach (var symb in realValuedSymbols) {
-        SetAllowedChild(StartSymbol, symb, 0);
+        AddAllowedChildSymbol(StartSymbol, symb);
       }
 
       foreach (var symb in unaryFunctionSymbols) {
         foreach (var childSymb in realValuedSymbols) {
-          SetAllowedChild(symb, childSymb, 0);
+          AddAllowedChildSymbol(symb, childSymb);
         }
       }
@@ -153,32 +149,29 @@
       foreach (var symb in binaryFunctionSymbols) {
         foreach (var childSymb in realValuedSymbols) {
-          SetAllowedChild(symb, childSymb, 0);
-          SetAllowedChild(symb, childSymb, 1);
+          AddAllowedChildSymbol(symb, childSymb);
         }
       }
 
       foreach (var childSymb in booleanSymbols) {
-        SetAllowedChild(@if, childSymb, 0);
+        AddAllowedChildSymbol(@if, childSymb, 0);
       }
       foreach (var childSymb in realValuedSymbols) {
-        SetAllowedChild(@if, childSymb, 1);
-        SetAllowedChild(@if, childSymb, 2);
+        AddAllowedChildSymbol(@if, childSymb, 1);
+        AddAllowedChildSymbol(@if, childSymb, 2);
       }
 
       foreach (var symb in relationalFunctionSymbols) {
         foreach (var childSymb in realValuedSymbols) {
-          SetAllowedChild(symb, childSymb, 0);
-          SetAllowedChild(symb, childSymb, 1);
+          AddAllowedChildSymbol(symb, childSymb);
         }
       }
       foreach (var symb in binaryBooleanFunctionSymbols) {
         foreach (var childSymb in booleanSymbols) {
-          SetAllowedChild(symb, childSymb, 0);
-          SetAllowedChild(symb, childSymb, 1);
+          AddAllowedChildSymbol(symb, childSymb);
         }
       }
       foreach (var symb in unaryBooleanFunctionSymbols) {
         foreach (var childSymb in booleanSymbols) {
-          SetAllowedChild(symb, childSymb, 0);
+          AddAllowedChildSymbol(symb, childSymb);
         }
       }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisGrammar.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisGrammar.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisGrammar.cs	(revision 5686)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public interface ISymbolicDataAnalysisGrammar : ISymbolicExpressionTreeGrammar {
+  public interface ISymbolicDataAnalysisGrammar : ISymbolicExpressionGrammar {
   }
 }
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/SymbolicDataAnalysisExpressionTreeInterpreterTest.cs	(revision 5686)
@@ -25,5 +25,4 @@
 using System.Linq;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Problems.DataAnalysis.Symbolic;
 using HeuristicLab.Random;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
@@ -59,9 +58,9 @@
       var twister = new MersenneTwister(31415);
       var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
-      var grammar = new GlobalSymbolicExpressionGrammar(new FullFunctionalExpressionGrammar());
-      grammar.MaxFunctionArguments = 0;
-      grammar.MaxFunctionDefinitions = 0;
-      grammar.MinFunctionArguments = 0;
-      grammar.MinFunctionDefinitions = 0;
+      var grammar = new FullFunctionalExpressionGrammar();
+      grammar.MaximumFunctionArguments = 0;
+      grammar.MaximumFunctionDefinitions = 0;
+      grammar.MinimumFunctionArguments = 0;
+      grammar.MinimumFunctionDefinitions = 0;
       var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
       double[] estimation = new double[Rows];
@@ -78,9 +77,9 @@
       var twister = new MersenneTwister(31415);
       var dataset = Util.CreateRandomDataset(twister, Rows, Columns);
-      var grammar = new GlobalSymbolicExpressionGrammar(new ArithmeticExpressionGrammar());
-      grammar.MaxFunctionArguments = 0;
-      grammar.MaxFunctionDefinitions = 0;
-      grammar.MinFunctionArguments = 0;
-      grammar.MinFunctionDefinitions = 0;
+      var grammar = new ArithmeticExpressionGrammar();
+      grammar.MaximumFunctionArguments = 0;
+      grammar.MaximumFunctionDefinitions = 0;
+      grammar.MinimumFunctionArguments = 0;
+      grammar.MinimumFunctionDefinitions = 0;
       var randomTrees = Util.CreateRandomTrees(twister, dataset, grammar, N, 1, 100, 0, 0);
       double[] estimation = new double[Rows];
Index: branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/Util.cs
===================================================================
--- branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/Util.cs	(revision 5685)
+++ branches/DataAnalysis Refactoring/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Tests/Util.cs	(revision 5686)
@@ -45,9 +45,9 @@
 
 
-    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionTreeGrammar grammar, int popSize) {
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar, int popSize) {
       return CreateRandomTrees(twister, dataset, grammar, popSize, 1, 200, 3, 3);
     }
 
-    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionTreeGrammar grammar,
+    public static ISymbolicExpressionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, ISymbolicExpressionGrammar grammar,
       int popSize, int minSize, int maxSize,
       int maxFunctionDefinitions, int maxFunctionArguments) {
@@ -57,5 +57,5 @@
       ISymbolicExpressionTree[] randomTrees = new ISymbolicExpressionTree[popSize];
       for (int i = 0; i < randomTrees.Length; i++) {
-        randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10, maxFunctionDefinitions, maxFunctionArguments);
+        randomTrees[i] = ProbabilisticTreeCreator.Create(twister, grammar, maxSize, 10);
       }
       return randomTrees;
