Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionSymbolFrequencyAnalyzer.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionSymbolFrequencyAnalyzer.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Analyzers/SymbolicExpressionSymbolFrequencyAnalyzer.cs	(revision 6387)
@@ -126,5 +126,5 @@
           string symbolName;
           if (aggregateDifferentNumberOfSubtrees) symbolName = node.Symbol.Name;
-          else symbolName = node.Symbol.Name + "-" + node.SubtreesCount;
+          else symbolName = node.Symbol.Name + "-" + node.SubtreeCount;
           if (symbolFrequencies.ContainsKey(symbolName)) symbolFrequencies[symbolName] += 1;
           else symbolFrequencies.Add(symbolName, 1);
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 6387)
@@ -62,5 +62,5 @@
       foreach (var node in branch.IterateNodesPrefix()) {
         Instruction instr = new Instruction();
-        int subtreesCount = node.SubtreesCount;
+        int subtreesCount = node.SubtreeCount;
         if (subtreesCount > 255) throw new ArgumentException("Number of subtrees is too big (>255)");
         instr.nArguments = (byte)subtreesCount;
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Crossovers/SubtreeCrossover.cs	(revision 6387)
@@ -133,6 +133,6 @@
       if (newChild == null) {
         // make sure that one subtree can be removed and that only the last subtree is removed 
-        return parent.Grammar.GetMinimumSubtreeCount(parent.Symbol) < parent.SubtreesCount &&
-          cutPoint.ChildIndex == parent.SubtreesCount - 1;
+        return parent.Grammar.GetMinimumSubtreeCount(parent.Symbol) < parent.SubtreeCount &&
+          cutPoint.ChildIndex == parent.SubtreeCount - 1;
       } else {
         // check syntax constraints of direct parent - child relation
@@ -146,6 +146,6 @@
             result &&
             parent.Grammar.ContainsSymbol(n.Symbol) &&
-            n.SubtreesCount >= parent.Grammar.GetMinimumSubtreeCount(n.Symbol) &&
-            n.SubtreesCount <= parent.Grammar.GetMaximumSubtreeCount(n.Symbol);
+            n.SubtreeCount >= parent.Grammar.GetMinimumSubtreeCount(n.Symbol) &&
+            n.SubtreeCount <= parent.Grammar.GetMaximumSubtreeCount(n.Symbol);
         });
         return result;
@@ -169,7 +169,7 @@
           }
           // add one additional extension point if the number of sub trees for the symbol is not full
-          if (n.SubtreesCount < n.Grammar.GetMaximumSubtreeCount(n.Symbol)) {
+          if (n.SubtreeCount < n.Grammar.GetMaximumSubtreeCount(n.Symbol)) {
             // empty extension point
-            internalCrossoverPoints.Add(new CutPoint(n, n.SubtreesCount));
+            internalCrossoverPoints.Add(new CutPoint(n, n.SubtreeCount));
           }
         }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbol.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbol.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbol.cs	(revision 6387)
@@ -30,4 +30,7 @@
     bool Fixed { get; set; }
 
+    int MinimumArity { get; }
+    int MaximumArity { get; }
+
     event EventHandler Changed;
   }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionTreeNode.cs	(revision 6387)
@@ -39,5 +39,5 @@
 
     IEnumerable<ISymbolicExpressionTreeNode> Subtrees { get; }
-    int SubtreesCount { get; }
+    int SubtreeCount { get; }
     ISymbolicExpressionTreeNode GetSubtree(int index);
     int IndexOfSubtree(ISymbolicExpressionTreeNode tree);
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6387)
@@ -143,5 +143,5 @@
     private void AddSymbolToDictionaries(ISymbol symbol) {
       symbols.Add(symbol.Name, symbol);
-      symbolSubtreeCount.Add(symbol.Name, Tuple.Create(0, 0));
+      symbolSubtreeCount.Add(symbol.Name, Tuple.Create(symbol.MinimumArity, symbol.MaximumArity));
       RegisterSymbolEvents(symbol);
     }
@@ -315,9 +315,15 @@
     protected void SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount) {
       var groupSymbol = symbol as GroupSymbol;
-      if (groupSymbol != null)
-        foreach (ISymbol s in groupSymbol.Flatten().Where(s => !(s is GroupSymbol)))
+      if (groupSymbol != null) {
+        var symbols = groupSymbol.Flatten().Where(s => !(s is GroupSymbol));
+        if (symbols.Any(s => s.MinimumArity > minimumSubtreeCount)) throw new ArgumentException("Invalid minimum subtree count " + minimumSubtreeCount + " for " + symbol);
+        if (symbols.Any(s => s.MaximumArity < maximumSubtreeCount)) throw new ArgumentException("Invalid minimum subtree count " + minimumSubtreeCount + " for " + symbol);
+        foreach (ISymbol s in symbols)
           SetSubTreeCountInDictionaries(s, minimumSubtreeCount, maximumSubtreeCount);
-      else
+      } else {
+        if (symbol.MinimumArity > minimumSubtreeCount) throw new ArgumentException("Invalid minimum subtree count " + minimumSubtreeCount + " for " + symbol);
+        if (symbol.MaximumArity < maximumSubtreeCount) throw new ArgumentException("Invalid minimum subtree count " + minimumSubtreeCount + " for " + symbol);
         SetSubTreeCountInDictionaries(symbol, minimumSubtreeCount, maximumSubtreeCount);
+      }
 
       ClearCaches();
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 6387)
@@ -126,5 +126,5 @@
     public virtual void ShakeLocalParameters(IRandom random, double shakingFactor) { }
 
-    public int SubtreesCount {
+    public int SubtreeCount {
       get {
         if (subtrees == null) return 0;
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Argument.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Argument.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Argument.cs	(revision 6387)
@@ -32,4 +32,14 @@
     public const string ArgumentName = "Argument";
     public const string ArgumentDescription = "Symbol that represents a function argument.";
+    private const int minimumArity = 0;
+    private const int maximumArity = 0;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
+
     [Storable]
     private int argumentIndex;
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Defun.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Defun.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Defun.cs	(revision 6387)
@@ -32,4 +32,13 @@
     public const string DefunName = "Defun";
     public const string DefunDescription = "Symbol that represents a function defining node.";
+    private const int minimumArity = 1;
+    private const int maximumArity = 1;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
 
     [StorableConstructor]
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/GroupSymbol.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/GroupSymbol.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/GroupSymbol.cs	(revision 6387)
@@ -28,4 +28,14 @@
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   public sealed class GroupSymbol : Symbol {
+    private const int minimumArity = 0;
+    private const int maximumArity = 0;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
+
     private ObservableSet<ISymbol> symbols;
     public IObservableSet<ISymbol> SymbolsCollection {
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/InvokeFunction.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/InvokeFunction.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/InvokeFunction.cs	(revision 6387)
@@ -32,4 +32,13 @@
     public const string InvokeFunctionName = "InvokeFunction";
     public const string InvokeFunctionDescription = "Symbol that the invocation of another function.";
+    private const int minimumArity = 0;
+    private const int maximumArity = byte.MaxValue;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
 
     [Storable]
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/ProgramRootSymbol.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/ProgramRootSymbol.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/ProgramRootSymbol.cs	(revision 6387)
@@ -29,4 +29,13 @@
     public const string ProgramRootSymbolName = "ProgramRootSymbol";
     public const string ProgramRootSymbolDescription = "Special symbol that represents the program root node of a symbolic expression tree.";
+    private const int minimumArity = 1;
+    private const int maximumArity = byte.MaxValue;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
 
     [StorableConstructor]
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs	(revision 6387)
@@ -29,7 +29,18 @@
     public const string StartSymbolName = "StartSymbol";
     public const string StartSymbolDescription = "Special symbol that represents the starting node of the result producing branch of a symbolic expression tree.";
+    private const int minimumArity = 1;
+    private const int maximumArity = 1;
+
+    public override int MinimumArity {
+      get { return minimumArity; }
+    }
+    public override int MaximumArity {
+      get { return maximumArity; }
+    }
 
     [StorableConstructor]
-    private StartSymbol(bool deserializing) : base(deserializing) { }
+    private StartSymbol(bool deserializing)
+      : base(deserializing) {
+    }
     private StartSymbol(StartSymbol original, Cloner cloner) : base(original, cloner) { }
     public StartSymbol() : base(StartSymbol.StartSymbolName, StartSymbol.StartSymbolDescription) { }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Symbol.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Symbol.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Symbol.cs	(revision 6387)
@@ -73,4 +73,7 @@
       get { return false; }
     }
+
+    public abstract int MinimumArity { get; }
+    public abstract int MaximumArity { get; }
     #endregion
 
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Grammars.cs	(revision 6387)
@@ -27,7 +27,16 @@
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding_3._4.Tests {
   public static class Grammars {
-
     [StorableClass]
     private class Addition : Symbol {
+      private const int minimumArity = 1;
+      private const int maximumArity = byte.MaxValue;
+
+      public override int MinimumArity {
+        get { return minimumArity; }
+      }
+      public override int MaximumArity {
+        get { return maximumArity; }
+      }
+
       [StorableConstructor]
       protected Addition(bool deserializing) : base(deserializing) { }
@@ -41,4 +50,14 @@
     [StorableClass]
     private class Subtraction : Symbol {
+      private const int minimumArity = 1;
+      private const int maximumArity = byte.MaxValue;
+
+      public override int MinimumArity {
+        get { return minimumArity; }
+      }
+      public override int MaximumArity {
+        get { return maximumArity; }
+      }
+
       [StorableConstructor]
       protected Subtraction(bool deserializing) : base(deserializing) { }
@@ -52,4 +71,14 @@
     [StorableClass]
     private class Multiplication : Symbol {
+      private const int minimumArity = 1;
+      private const int maximumArity = byte.MaxValue;
+
+      public override int MinimumArity {
+        get { return minimumArity; }
+      }
+      public override int MaximumArity {
+        get { return maximumArity; }
+      }
+
       [StorableConstructor]
       protected Multiplication(bool deserializing) : base(deserializing) { }
@@ -63,4 +92,14 @@
     [StorableClass]
     private class Division : Symbol {
+      private const int minimumArity = 1;
+      private const int maximumArity = byte.MaxValue;
+
+      public override int MinimumArity {
+        get { return minimumArity; }
+      }
+      public override int MaximumArity {
+        get { return maximumArity; }
+      }
+
       [StorableConstructor]
       protected Division(bool deserializing) : base(deserializing) { }
@@ -74,4 +113,14 @@
     [StorableClass]
     private class Terminal : Symbol {
+      private const int minimumArity = 0;
+      private const int maximumArity = 0;
+
+      public override int MinimumArity {
+        get { return minimumArity; }
+      }
+      public override int MaximumArity {
+        get { return maximumArity; }
+      }
+
       [StorableConstructor]
       protected Terminal(bool deserializing) : base(deserializing) { }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs	(revision 6379)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Tests/Util.cs	(revision 6387)
@@ -122,5 +122,5 @@
 
         foreach (var argTreenode in defunTreeNode.IterateNodesPrefix().OfType<ArgumentTreeNode>()) {
-          Assert.IsTrue(argTreenode.SubtreesCount == 0);
+          Assert.IsTrue(argTreenode.SubtreeCount == 0);
           Assert.IsTrue(((Argument)argTreenode.Symbol).ArgumentIndex < arity);
         }
