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 6295)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbol.cs	(revision 6296)
@@ -27,4 +27,5 @@
     ISymbolicExpressionTreeNode CreateTreeNode();
     double InitialFrequency { get; set; }
+    bool Enabled { get; set; }
     bool Fixed { get; set; }
 
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6295)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6296)
@@ -36,4 +36,5 @@
   [StorableClass]
   public abstract class SymbolicExpressionGrammarBase : NamedItem, ISymbolicExpressionGrammarBase {
+
     #region properties for separation between implementation and persistence
     [Storable(Name = "Symbols")]
@@ -62,4 +63,5 @@
     #endregion
 
+    protected bool suppressEvents;
     protected Dictionary<string, ISymbol> symbols;
     protected Dictionary<string, Tuple<int, int>> symbolSubtreeCount;
@@ -80,4 +82,6 @@
       cachedMaxExpressionLength = new Dictionary<string, int>();
       cachedMinExpressionDepth = new Dictionary<string, int>();
+
+      suppressEvents = false;
     }
     [StorableHook(HookType.AfterDeserialization)]
@@ -106,4 +110,6 @@
       foreach (ISymbol symbol in symbols.Values)
         RegisterSymbolEvents(symbol);
+
+      suppressEvents = false;
     }
 
@@ -118,73 +124,30 @@
       allowedChildSymbols = new Dictionary<string, List<string>>();
       allowedChildSymbolsPerIndex = new Dictionary<Tuple<string, int>, List<string>>();
+
+      suppressEvents = false;
     }
 
     #region protected grammar manipulation methods
     protected void AddSymbol(ISymbol symbol) {
-      if (ContainsSymbol(symbol)) throw new ArgumentException("Symbol " + symbol + " is already defined.");
-      RegisterSymbolEvents(symbol);
       symbols.Add(symbol.Name, symbol);
       symbolSubtreeCount.Add(symbol.Name, Tuple.Create(0, 0));
+      RegisterSymbolEvents(symbol);
+
+      var groupSymbol = symbol as GroupSymbol;
+      if (groupSymbol != null) AddSymbol(groupSymbol);
+
       ClearCaches();
       OnChanged();
     }
 
-    private void RegisterSymbolEvents(ISymbol symbol) {
-      symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
-      symbol.NameChanged += new EventHandler(Symbol_NameChanged);
-      symbol.Changed += new EventHandler(Symbol_Changed);
-    }
-    private void DeregisterSymbolEvents(ISymbol symbol) {
-      symbol.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
-      symbol.NameChanged -= new EventHandler(Symbol_NameChanged);
-      symbol.Changed -= new EventHandler(Symbol_Changed);
-    }
-
-    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
-      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
-    }
-    private void Symbol_NameChanged(object sender, EventArgs e) {
-      ISymbol symbol = (ISymbol)sender;
-      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
-      string newName = symbol.Name;
-
-      symbols.Remove(oldName);
-      symbols.Add(newName, symbol);
-
-      var subtreeCount = symbolSubtreeCount[oldName];
-      symbolSubtreeCount.Remove(oldName);
-      symbolSubtreeCount.Add(newName, subtreeCount);
-
-      List<string> allowedChilds;
-      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
-        allowedChildSymbols.Remove(oldName);
-        allowedChildSymbols.Add(newName, allowedChilds);
-      }
-
-      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
-        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
-          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
-          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
-        }
-      }
-
-      foreach (var parent in Symbols) {
-        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
-          if (allowedChilds.Remove(oldName))
-            allowedChilds.Add(newName);
-
-        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
-          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
-            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
-        }
-      }
-
-      ClearCaches();
-      OnChanged();
-    }
-
-    private void Symbol_Changed(object sende, EventArgs e) {
-      ClearCaches();
-      OnChanged();
+    private void AddSymbol(GroupSymbol groupSymbol) {
+      foreach (ISymbol symbol in groupSymbol.Symbols) {
+        symbols.Add(symbol.Name, symbol);
+        symbolSubtreeCount.Add(symbol.Name, Tuple.Create(0, 0));
+        RegisterSymbolEvents(symbol);
+
+        var childGroup = symbol as GroupSymbol;
+        if (childGroup != null) AddSymbol(childGroup);
+      }
     }
 
@@ -218,4 +181,9 @@
 
     protected void AddAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      suppressEvents = true;
+      for (int argumentIndex = 0; argumentIndex < GetMaximumSubtreeCount(parent); argumentIndex++)
+        RemoveAllowedChildSymbol(parent, child, argumentIndex);
+      suppressEvents = false;
+
       List<string> childSymbols;
       if (!allowedChildSymbols.TryGetValue(parent.Name, out childSymbols)) {
@@ -223,13 +191,18 @@
         allowedChildSymbols.Add(parent.Name, childSymbols);
       }
-      if (childSymbols.Contains(child.Name)) throw new ArgumentException();
-      childSymbols.Add(child.Name);
-      ClearCaches();
-      OnChanged();
+
+      if (!childSymbols.Contains(child.Name)) {
+        childSymbols.Add(child.Name);
+        ClearCaches();
+        OnChanged();
+      }
     }
 
     protected void AddAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      List<string> childSymbols;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out childSymbols))
+        if (childSymbols.Contains(child.Name)) return;
+
       var key = Tuple.Create(parent.Name, argumentIndex);
-      List<string> childSymbols;
       if (!allowedChildSymbolsPerIndex.TryGetValue(key, out childSymbols)) {
         childSymbols = new List<string>();
@@ -237,29 +210,55 @@
       }
 
-      if (IsAllowedChildSymbol(parent, child)) throw new ArgumentException();
-      if (childSymbols.Contains(child.Name)) throw new ArgumentException();
-      childSymbols.Add(child.Name);
-      ClearCaches();
-      OnChanged();
+      if (!childSymbols.Contains(child.Name)) {
+        childSymbols.Add(child.Name);
+        ClearCaches();
+        OnChanged();
+      }
     }
 
     protected void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      bool changed = false;
       List<string> childSymbols;
       if (allowedChildSymbols.TryGetValue(child.Name, out childSymbols)) {
-        if (allowedChildSymbols[parent.Name].Remove(child.Name)) {
-          ClearCaches();
-          OnChanged();
+        if (allowedChildSymbols[parent.Name].Remove(child.Name)) changed = true;
+      }
+
+      for (int argumentIndex = 0; argumentIndex < GetMaximumSubtreeCount(parent); argumentIndex++) {
+        var key = Tuple.Create(parent.Name, argumentIndex);
+        if (allowedChildSymbolsPerIndex.TryGetValue(key, out childSymbols)) {
+          if (allowedChildSymbolsPerIndex[key].Remove(child.Name)) changed = true;
         }
       }
+
+      if (changed) {
+        ClearCaches();
+        OnChanged();
+      }
     }
 
     protected void RemoveAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      bool changed = false;
+
+      List<string> childSymbols;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out childSymbols)) {
+        if (childSymbols.Remove(child.Name)) {
+          suppressEvents = true;
+          for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
+            if (i != argumentIndex) AddAllowedChildSymbol(parent, child, i);
+          }
+          suppressEvents = false;
+          changed = true;
+        }
+      }
+
       var key = Tuple.Create(parent.Name, argumentIndex);
-      List<string> childSymbols;
       if (allowedChildSymbolsPerIndex.TryGetValue(key, out childSymbols)) {
-        if (allowedChildSymbolsPerIndex[key].Remove(child.Name)) {
-          ClearCaches();
-          OnChanged();
-        }
+        if (allowedChildSymbolsPerIndex[key].Remove(child.Name))
+          changed = true;
+      }
+
+      if (changed) {
+        ClearCaches();
+        OnChanged();
       }
     }
@@ -277,10 +276,9 @@
     #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)); }
+      get { return Symbols.Where(s => s.Enabled); }
     }
     public virtual bool ContainsSymbol(ISymbol symbol) {
@@ -289,4 +287,6 @@
 
     public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child) {
+      if (!child.Enabled) return false;
+
       List<string> temp;
       if (allowedChildSymbols.TryGetValue(parent.Name, out temp))
@@ -296,4 +296,6 @@
 
     public virtual bool IsAllowedChildSymbol(ISymbol parent, ISymbol child, int argumentIndex) {
+      if (!child.Enabled) return false;
+
       List<string> temp;
       if (allowedChildSymbols.TryGetValue(parent.Name, out temp))
@@ -307,5 +309,8 @@
 
     public virtual IEnumerable<ISymbol> GetAllowedChildSymbols(ISymbol parent) {
-      return from s in AllowedSymbols where IsAllowedChildSymbol(parent, s) select s;
+      List<string> childs;
+      if (allowedChildSymbols.TryGetValue(parent.Name, out childs))
+        return childs.Select(s => GetSymbol(s)).Where(s => s.Enabled);
+      return Enumerable.Empty<ISymbol>();
     }
 
@@ -320,5 +325,5 @@
         result = result.Union(temp);
 
-      return result.Select(x => GetSymbol(x)).Where(s => !s.InitialFrequency.IsAlmost(0.0));
+      return result.Select(x => GetSymbol(x)).Where(s => s.Enabled);
     }
 
@@ -342,6 +347,5 @@
         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 AllowedSymbols
-                                                                      where IsAllowedChildSymbol(symbol, s, argIndex)
+                                              let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
                                                                       select GetMinimumExpressionLength(s)).DefaultIfEmpty(0).Min()
                                               select minForSlot).DefaultIfEmpty(0).Sum();
@@ -359,6 +363,5 @@
         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 AllowedSymbols
-                                                          where IsAllowedChildSymbol(symbol, s, argIndex)
+                                  let maxForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
                                                           select GetMaximumExpressionLength(s)).DefaultIfEmpty(0).Max()
                                   select maxForSlot).DefaultIfEmpty(0).Sum();
@@ -375,6 +378,5 @@
         cachedMinExpressionDepth[symbol.Name] = int.MaxValue; // prevent infinite recursion
         long minDepth = 1 + (from argIndex in Enumerable.Range(0, GetMinimumSubtreeCount(symbol))
-                             let minForSlot = (long)(from s in AllowedSymbols
-                                                     where IsAllowedChildSymbol(symbol, s, argIndex)
+                             let minForSlot = (long)(from s in GetAllowedChildSymbols(symbol, argIndex)
                                                      select GetMinimumExpressionDepth(s)).DefaultIfEmpty(0).Min()
                              select minForSlot).DefaultIfEmpty(0).Max();
@@ -385,6 +387,68 @@
     }
 
+
+    #region events
+    private void RegisterSymbolEvents(ISymbol symbol) {
+      symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
+      symbol.NameChanged += new EventHandler(Symbol_NameChanged);
+      symbol.Changed += new EventHandler(Symbol_Changed);
+    }
+    private void DeregisterSymbolEvents(ISymbol symbol) {
+      symbol.NameChanging -= new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
+      symbol.NameChanged -= new EventHandler(Symbol_NameChanged);
+      symbol.Changed -= new EventHandler(Symbol_Changed);
+    }
+
+    private void Symbol_NameChanging(object sender, CancelEventArgs<string> e) {
+      if (symbols.ContainsKey(e.Value)) e.Cancel = true;
+    }
+    private void Symbol_NameChanged(object sender, EventArgs e) {
+      ISymbol symbol = (ISymbol)sender;
+      string oldName = symbols.Where(x => x.Value == symbol).First().Key;
+      string newName = symbol.Name;
+
+      symbols.Remove(oldName);
+      symbols.Add(newName, symbol);
+
+      var subtreeCount = symbolSubtreeCount[oldName];
+      symbolSubtreeCount.Remove(oldName);
+      symbolSubtreeCount.Add(newName, subtreeCount);
+
+      List<string> allowedChilds;
+      if (allowedChildSymbols.TryGetValue(oldName, out allowedChilds)) {
+        allowedChildSymbols.Remove(oldName);
+        allowedChildSymbols.Add(newName, allowedChilds);
+      }
+
+      for (int i = 0; i < GetMaximumSubtreeCount(symbol); i++) {
+        if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(oldName, i), out allowedChilds)) {
+          allowedChildSymbolsPerIndex.Remove(Tuple.Create(oldName, i));
+          allowedChildSymbolsPerIndex.Add(Tuple.Create(newName, i), allowedChilds);
+        }
+      }
+
+      foreach (var parent in Symbols) {
+        if (allowedChildSymbols.TryGetValue(parent.Name, out allowedChilds))
+          if (allowedChilds.Remove(oldName))
+            allowedChilds.Add(newName);
+
+        for (int i = 0; i < GetMaximumSubtreeCount(parent); i++) {
+          if (allowedChildSymbolsPerIndex.TryGetValue(Tuple.Create(parent.Name, i), out allowedChilds))
+            if (allowedChilds.Remove(oldName)) allowedChilds.Add(newName);
+        }
+      }
+
+      ClearCaches();
+      OnChanged();
+    }
+
+    private void Symbol_Changed(object sende, EventArgs e) {
+      ClearCaches();
+      OnChanged();
+    }
+
     public event EventHandler Changed;
     protected virtual void OnChanged() {
+      if (suppressEvents) return;
       var handler = Changed;
       if (handler != null) Changed(this, EventArgs.Empty);
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 6295)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/GroupSymbol.cs	(revision 6296)
@@ -32,5 +32,14 @@
     public IEnumerable<ISymbol> Symbols {
       get { return symbols; }
-      private set { symbols = new List<ISymbol>(value); }
+    }
+
+    public override bool Enabled {
+      get { return base.Enabled; }
+      set {
+        if (value != Enabled) {
+          base.Enabled = value;
+          symbols.ForEach(s => s.Enabled = value);
+        }
+      }
     }
 
@@ -39,4 +48,5 @@
     private GroupSymbol(GroupSymbol original, Cloner cloner)
       : base(original, cloner) {
+      symbols = original.Symbols.Select(s => cloner.Clone(s)).ToList();
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -44,9 +54,8 @@
     }
 
-    public GroupSymbol(string name) : this(name, "A symbol to group other symbols.") { }
-    public GroupSymbol(string name, string description) : this(name, description, Enumerable.Empty<ISymbol>()) { }
-    public GroupSymbol(string name, string description, IEnumerable<ISymbol> symbols)
-      : base(name, description) {
+    public GroupSymbol(string name, IEnumerable<ISymbol> symbols)
+      : base(name, "A symbol which groups other symbols") {
       this.symbols = new List<ISymbol>(symbols);
+      InitialFrequency = 0.0;
     }
   }
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 6295)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/Symbol.cs	(revision 6296)
@@ -38,4 +38,17 @@
         if (value != initialFrequency) {
           initialFrequency = value;
+          if (initialFrequency.IsAlmost(0.0)) enabled = false;
+          OnChanged(EventArgs.Empty);
+        }
+      }
+    }
+
+    [Storable(DefaultValue = true)]
+    private bool enabled;
+    public virtual bool Enabled {
+      get { return enabled; }
+      set {
+        if (value != enabled) {
+          enabled = value;
           OnChanged(EventArgs.Empty);
         }
@@ -68,4 +81,5 @@
       : base(original, cloner) {
       initialFrequency = original.initialFrequency;
+      enabled = original.enabled;
       @fixed = original.@fixed;
     }
@@ -74,5 +88,11 @@
       : base(name, description) {
       initialFrequency = 1.0;
+      enabled = true;
       @fixed = false;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (initialFrequency.IsAlmost(0.0)) enabled = false;
     }
 
@@ -81,5 +101,4 @@
     }
 
-    #region events
     public event EventHandler Changed;
     protected virtual void OnChanged(EventArgs e) {
@@ -88,5 +107,4 @@
         handlers(this, e);
     }
-    #endregion
   }
 }
