Index: /branches/GP.Grammar.Editor/HeuristicLab.Common/3.3/ObjectExtensions.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Common/3.3/ObjectExtensions.cs	(revision 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Common/3.3/ObjectExtensions.cs	(revision 6493)
@@ -24,12 +24,27 @@
 using System.Collections.Generic;
 using System.Collections.Specialized;
+using System.Linq;
 using System.Reflection;
-using System.Threading;
 
 namespace HeuristicLab.Common {
   public static class ObjectExtensions {
     public static IEnumerable<object> GetObjectGraphObjects(this object obj) {
+      if (obj == null) return Enumerable.Empty<object>();
+
       var objects = new HashSet<object>();
-      obj.CollectObjectGraphObjects(objects);
+      var stack = new Stack<object>();
+
+      stack.Push(obj);
+      while (stack.Count > 0) {
+        object current = stack.Pop();
+        Type type = obj.GetType();
+        objects.Add(current);
+
+        foreach (object o in GetChildObjects(current)) {
+          if (o != null && !objects.Contains(o) && !ExcludeType(o.GetType()))
+            stack.Push(o);
+        }
+      }
+
       return objects;
     }
@@ -45,46 +60,36 @@
     /// compared to traverse their internal data structures.
     /// </summary>
-    private static void CollectObjectGraphObjects(this object obj, HashSet<object> objects) {
-      if (obj == null || objects.Contains(obj)) return;
+    private static bool ExcludeType(Type type) {
+      return type.IsPrimitive ||
+             type == typeof(string) ||
+             type == typeof(decimal) ||
+             typeof(Delegate).IsAssignableFrom(type) ||
+             typeof(Pointer).IsAssignableFrom(type) ||
+             (type.HasElementType && ExcludeType(type.GetElementType()));
+    }
+    private static IEnumerable<object> GetChildObjects(object obj) {
       Type type = obj.GetType();
-      if (ExcludeType(type)) return;
-      if (type.HasElementType && ExcludeType(type.GetElementType())) return;
 
-      objects.Add(obj);
-
-      if (type.IsSubclassOfRawGeneric(typeof(ThreadLocal<>))) return; // avoid stack overflow when the field `ConcurrentStack<int> s_availableIndices` too grows large
-      
-      // performance critical to handle dictionaries, hashsets and hashtables in a special way
-      if (type.IsSubclassOfRawGeneric(typeof(Dictionary<,>)) || 
-          type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) || 
-          type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) ||
-          obj is SortedList || 
-          obj is OrderedDictionary || 
-          obj is ListDictionary || 
-          obj is Hashtable) {        
+      if (type.IsSubclassOfRawGeneric(typeof(Dictionary<,>)) ||
+         type.IsSubclassOfRawGeneric(typeof(SortedDictionary<,>)) ||
+         type.IsSubclassOfRawGeneric(typeof(SortedList<,>)) ||
+         obj is SortedList ||
+         obj is OrderedDictionary ||
+         obj is ListDictionary ||
+         obj is Hashtable) {
         var dictionary = obj as IDictionary;
         foreach (object value in dictionary.Keys)
-          CollectObjectGraphObjects(value, objects);
+          yield return value;
         foreach (object value in dictionary.Values)
-          CollectObjectGraphObjects(value, objects);
-        return;
+          yield return value;
       } else if (type.IsArray || type.IsSubclassOfRawGeneric(typeof(HashSet<>))) {
         var enumerable = obj as IEnumerable;
         foreach (var value in enumerable)
-          CollectObjectGraphObjects(value, objects);
-        return;
+          yield return value;
+      } else {
+        foreach (FieldInfo f in type.GetAllFields()) {
+          yield return f.GetValue(obj);
+        }
       }
-
-      foreach (FieldInfo f in type.GetAllFields()) {
-        f.GetValue(obj).CollectObjectGraphObjects(objects);
-      }
-    }
-
-    private static bool ExcludeType(Type type) {
-      return type.IsPrimitive ||
-             type == typeof(string) || 
-             type == typeof(decimal) ||
-             typeof(Delegate).IsAssignableFrom(type) || 
-             typeof(Pointer).IsAssignableFrom(type);
     }
   }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.cs	(revision 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.cs	(revision 6493)
@@ -131,5 +131,4 @@
 
       symbolicExpressionTreeChart.SuspendRepaint = false;
-      symbolicExpressionTreeChart.Repaint();
       UpdateSelectedSymbolicExpressionTreeNodes();
     }
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.Designer.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.Designer.cs	(revision 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.Designer.cs	(revision 6493)
@@ -160,9 +160,11 @@
       this.symbolsTreeView.TabIndex = 0;
       this.symbolsTreeView.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.symbolsTreeView_AfterCheck);
-      this.symbolsTreeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.symbolsTreeView_ItemDrag);
       this.symbolsTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.symbolsTreeView_AfterSelect);
       this.symbolsTreeView.DragDrop += new System.Windows.Forms.DragEventHandler(this.symbolsTreeView_DragDrop);
       this.symbolsTreeView.DragEnter += new System.Windows.Forms.DragEventHandler(this.symbolsTreeView_DragEnter);
       this.symbolsTreeView.DragOver += new System.Windows.Forms.DragEventHandler(this.symbolsTreeView_DragOver);
+      this.symbolsTreeView.ItemDrag += new System.Windows.Forms.ItemDragEventHandler(this.symbolsTreeView_ItemDrag);
+      this.symbolsTreeView.KeyDown += new System.Windows.Forms.KeyEventHandler(this.symbolsTreeView_KeyDown);
+      this.symbolsTreeView.MouseDown += new System.Windows.Forms.MouseEventHandler(this.symbolsTreeView_MouseDown);
       // 
       // imageList
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.cs	(revision 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.cs	(revision 6493)
@@ -102,7 +102,6 @@
       UpdateSymbolsTreeView();
       if (symbol != null && Content.ContainsSymbol(symbol)) {
-        allowedChildSymbolsControl.Symbol = symbol;
-        symbolDetailsViewHost.Content = symbol;
-        symbolsTreeView.SelectedNode = IterateSymbolTreeNodes().Where(n => n.Tag == symbol).ToList().FirstOrDefault();
+        symbolsTreeView.SelectedNode = IterateTreeNodes().Where(n => n.Tag == symbol).ToList().FirstOrDefault();
+        UpdateSymbolDetailsViews();
       }
     }
@@ -111,5 +110,5 @@
     private void UpdateSymbolsTreeView() {
       var symbols = Content.Symbols.ToList();
-      foreach (var treeNode in IterateSymbolTreeNodes().ToList()) {
+      foreach (var treeNode in IterateTreeNodes().ToList()) {
         var symbol = treeNode.Tag as ISymbol;
         if (!symbols.Contains(symbol))
@@ -132,7 +131,7 @@
           node.Text = symbol.Name;
           node.Tag = symbol;
-          node.Checked = symbol.Enabled;
           collection.Add(node);
         }
+        node.Checked = symbol.Enabled;
         var groupSymbol = symbol as GroupSymbol;
         if (groupSymbol != null) AddChildTreeNodes(node.Nodes, groupSymbol.Symbols);
@@ -141,9 +140,6 @@
 
     private void symbolsTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
-      if (e.Action != TreeViewAction.Unknown) {
-        var symbol = (ISymbol)e.Node.Tag;
-        symbolDetailsViewHost.Content = symbol;
-        allowedChildSymbolsControl.Symbol = symbol;
-      }
+      if (e.Action != TreeViewAction.Unknown) UpdateSymbolDetailsViews();
+
       removeButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
       copyButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
@@ -156,11 +152,7 @@
         var symbol = (ISymbol)e.Node.Tag;
         symbol.Enabled = e.Node.Checked;
-        foreach (var node in IterateSymbolTreeNodes())
+        foreach (var node in IterateTreeNodes())
           node.Checked = ((ISymbol)node.Tag).Enabled;
 
-        if (symbolsTreeView.SelectedNode != null) {
-          symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
-          allowedChildSymbolsControl.Symbol = symbol;
-        }
         Content.FinishedGrammarManipulation();
       }
@@ -226,4 +218,29 @@
     #endregion
 
+    private void symbolsTreeView_MouseDown(object sender, MouseEventArgs e) {
+      // enables deselection of treeNodes
+      if (symbolsTreeView.SelectedNode == null) return;
+      Point coordinates = new Point(e.X, e.Y);
+      if (e.Button == System.Windows.Forms.MouseButtons.Left && symbolsTreeView.GetNodeAt(coordinates) == null) {
+        symbolsTreeView.SelectedNode = null;
+        symbolDetailsViewHost.Content = null;
+        SetEnabledStateOfControls();
+      }
+    }
+
+    private void symbolsTreeView_KeyDown(object sender, KeyEventArgs e) {
+      if (ReadOnly) return;
+      if (symbolsTreeView.SelectedNode == null) return;
+      if (e.KeyCode != Keys.Delete) return;
+
+      var symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
+      if (!(symbol is IReadOnlySymbol))
+        Content.RemoveSymbol(symbol);
+
+      SetEnabledStateOfControls();
+      UpdateSymbolDetailsViews();
+      RebuildImageList();
+    }
+
     #region button events
     private TypeSelectorDialog typeSelectorDialog;
@@ -256,6 +273,4 @@
       var symbol = symbolsTreeView.SelectedNode.Tag as ISymbol;
       if (symbol != null && !(symbol is IReadOnlySymbol)) {
-        allowedChildSymbolsControl.Symbol = null;
-        symbolDetailsViewHost.Content = null;
 
         Content.StartGrammarManipulation();
@@ -279,6 +294,4 @@
       if (symbol != null && !(symbol is IReadOnlySymbol)) {
         Content.RemoveSymbol(symbol);
-        allowedChildSymbolsControl.Symbol = null;
-        symbolDetailsViewHost.Content = null;
       }
     }
@@ -310,5 +323,4 @@
     }
 
-
     private void ChangeDuplicateSymbolNames(ISymbol symbol) {
       foreach (var s in symbol.Flatten()) {
@@ -322,5 +334,15 @@
     }
 
-    private IEnumerable<TreeNode> IterateSymbolTreeNodes(TreeNode node = null) {
+    private void UpdateSymbolDetailsViews() {
+      if (symbolsTreeView.SelectedNode != null) {
+        symbolDetailsViewHost.Content = (ISymbol)symbolsTreeView.SelectedNode.Tag;
+        allowedChildSymbolsControl.Symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
+      } else {
+        symbolDetailsViewHost.Content = null;
+        allowedChildSymbolsControl.Symbol = null;
+      }
+    }
+
+    private IEnumerable<TreeNode> IterateTreeNodes(TreeNode node = null) {
       TreeNodeCollection nodes;
       if (node == null)
@@ -332,5 +354,5 @@
 
       foreach (var childNode in nodes.OfType<TreeNode>())
-        foreach (var n in IterateSymbolTreeNodes(childNode))
+        foreach (var n in IterateTreeNodes(childNode))
           yield return n;
     }
@@ -338,9 +360,26 @@
     protected virtual void RebuildImageList() {
       symbolsTreeView.ImageList.Images.Clear();
-      foreach (TreeNode treeNode in IterateSymbolTreeNodes()) {
+      foreach (TreeNode treeNode in IterateTreeNodes()) {
         var symbol = (ISymbol)treeNode.Tag;
         symbolsTreeView.ImageList.Images.Add(symbol == null ? HeuristicLab.Common.Resources.VSImageLibrary.Nothing : symbol.ItemImage);
         treeNode.ImageIndex = symbolsTreeView.ImageList.Images.Count - 1;
       }
+    }
+
+    //necessary code to handle dock correctly regarding the expanded nodes
+    bool[] expandendedState;
+    protected override void OnHandleCreated(EventArgs e) {
+      base.OnHandleCreated(e);
+      if (expandendedState == null) return;
+      var nodes = IterateTreeNodes().ToList();
+      for (int i = 0; i < nodes.Count; i++)
+        if (expandendedState[i]) nodes[i].Expand();
+    }
+    protected override void OnHandleDestroyed(EventArgs e) {
+      base.OnHandleDestroyed(e);
+      var nodes = IterateTreeNodes().ToList();
+      expandendedState = new bool[nodes.Count];
+      for (int i = 0; i < nodes.Count; i++)
+        expandendedState[i] = nodes[i].IsExpanded;
     }
     #endregion
Index: /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs
===================================================================
--- /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6493)
@@ -426,17 +426,20 @@
       symbol.NameChanging += new EventHandler<CancelEventArgs<string>>(Symbol_NameChanging);
       symbol.NameChanged += new EventHandler(Symbol_NameChanged);
-      symbol.Changed += new EventHandler(Symbol_Changed);
+
       var groupSymbol = symbol as GroupSymbol;
       if (groupSymbol != null) RegisterGroupSymbolEvents(groupSymbol);
+      else 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);
+
       var groupSymbol = symbol as GroupSymbol;
       if (groupSymbol != null) DeregisterGroupSymbolEvents(groupSymbol);
+      else symbol.Changed -= new EventHandler(Symbol_Changed);
     }
 
     private void RegisterGroupSymbolEvents(GroupSymbol groupSymbol) {
+      groupSymbol.Changed += new EventHandler(GroupSymbol_Changed);
       groupSymbol.SymbolsCollection.ItemsAdded += new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsAdded);
       groupSymbol.SymbolsCollection.ItemsRemoved += new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsRemoved);
@@ -444,4 +447,5 @@
     }
     private void DeregisterGroupSymbolEvents(GroupSymbol groupSymbol) {
+      groupSymbol.Changed -= new EventHandler(GroupSymbol_Changed);
       groupSymbol.SymbolsCollection.ItemsAdded -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsAdded);
       groupSymbol.SymbolsCollection.ItemsRemoved -= new Collections.CollectionItemsChangedEventHandler<ISymbol>(GroupSymbol_ItemsRemoved);
@@ -492,5 +496,17 @@
     }
 
-    private void Symbol_Changed(object sende, EventArgs e) {
+    private void Symbol_Changed(object sender, EventArgs e) {
+      if (suppressEvents) return;
+      ClearCaches();
+      OnChanged();
+    }
+
+    private void GroupSymbol_Changed(object sender, EventArgs e) {
+      if (suppressEvents) return;
+      suppressEvents = true;
+      GroupSymbol groupSymbol = (GroupSymbol)sender;
+      foreach (ISymbol symbol in groupSymbol.Flatten())
+        symbol.Enabled = groupSymbol.Enabled;
+      suppressEvents = false;
       ClearCaches();
       OnChanged();
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 6492)
+++ /branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/GroupSymbol.cs	(revision 6493)
@@ -51,11 +51,5 @@
     public override bool Enabled {
       get { return base.Enabled; }
-      set {
-        if (value != Enabled) {
-          base.Enabled = value;
-          foreach (ISymbol symbol in symbols)
-            symbol.Enabled = value;
-        }
-      }
+      set { base.Enabled = value; }
     }
 
