Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views-3.4.csproj	(revision 6415)
@@ -110,4 +110,10 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="SymbolicExpressionGrammarAllowedChildSymbolsControl.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="SymbolicExpressionGrammarAllowedChildSymbolsControl.Designer.cs">
+      <DependentUpon>SymbolicExpressionGrammarAllowedChildSymbolsControl.cs</DependentUpon>
+    </Compile>
     <Compile Include="SymbolicExpressionGrammarEditorView.cs">
       <SubType>UserControl</SubType>
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.Designer.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.Designer.cs	(revision 6415)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.Designer.cs	(revision 6415)
@@ -0,0 +1,102 @@
+﻿#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.Views {
+  partial class SymbolicExpressionGrammarAllowedChildSymbolsControl {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.allowedChildSymbolsGroupBox = new System.Windows.Forms.GroupBox();
+      this.symbolicExpressionTreeChart = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart();
+      this.allowedChildSymbolsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // allowedChildSymbolsGroupBox
+      // 
+      this.allowedChildSymbolsGroupBox.Controls.Add(this.symbolicExpressionTreeChart);
+      this.allowedChildSymbolsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.allowedChildSymbolsGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.allowedChildSymbolsGroupBox.Name = "allowedChildSymbolsGroupBox";
+      this.allowedChildSymbolsGroupBox.Size = new System.Drawing.Size(651, 405);
+      this.allowedChildSymbolsGroupBox.TabIndex = 2;
+      this.allowedChildSymbolsGroupBox.TabStop = false;
+      this.allowedChildSymbolsGroupBox.Text = "Allowed Child Symbols";
+      // 
+      // allowedChildSymbolsControl
+      // 
+      this.symbolicExpressionTreeChart.AllowDrop = true;
+      this.symbolicExpressionTreeChart.BackgroundColor = System.Drawing.Color.White;
+      this.symbolicExpressionTreeChart.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.symbolicExpressionTreeChart.LineColor = System.Drawing.Color.Black;
+      this.symbolicExpressionTreeChart.Location = new System.Drawing.Point(3, 16);
+      this.symbolicExpressionTreeChart.Name = "allowedChildSymbolsControl";
+      this.symbolicExpressionTreeChart.Size = new System.Drawing.Size(645, 386);
+      this.symbolicExpressionTreeChart.Spacing = 5;
+      this.symbolicExpressionTreeChart.SuspendRepaint = false;
+      this.symbolicExpressionTreeChart.TabIndex = 0;
+      this.symbolicExpressionTreeChart.TextFont = new System.Drawing.Font("Times New Roman", 8F);
+      this.symbolicExpressionTreeChart.Tree = null;
+      this.symbolicExpressionTreeChart.SymbolicExpressionTreeNodeClicked += new System.Windows.Forms.MouseEventHandler(this.symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked);
+      this.symbolicExpressionTreeChart.DragDrop += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragDrop);
+      this.symbolicExpressionTreeChart.DragEnter += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragEnter);
+      this.symbolicExpressionTreeChart.DragOver += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragOver);
+      this.symbolicExpressionTreeChart.Paint += new System.Windows.Forms.PaintEventHandler(this.allowedChildSymbolsControl_Paint);
+      this.symbolicExpressionTreeChart.KeyDown += new System.Windows.Forms.KeyEventHandler(this.symbolicExpressionTreeChart_KeyDown);
+      this.symbolicExpressionTreeChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.allowedChildSymbolsControl_MouseDown);
+      // 
+      // SymbolicExpressionGrammarAllowedChildSymbolsControl
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.allowedChildSymbolsGroupBox);
+      this.Name = "SymbolicExpressionGrammarAllowedChildSymbolsControl";
+      this.Size = new System.Drawing.Size(651, 405);
+      this.allowedChildSymbolsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.GroupBox allowedChildSymbolsGroupBox;
+    private SymbolicExpressionTreeChart symbolicExpressionTreeChart;
+  }
+}
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 6415)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarAllowedChildSymbolsControl.cs	(revision 6415)
@@ -0,0 +1,326 @@
+﻿#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.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
+  public sealed partial class SymbolicExpressionGrammarAllowedChildSymbolsControl : UserControl {
+    private ObservableList<ISymbolicExpressionTreeNode> selectedSymbolicExpressionTreeNodes;
+
+    public SymbolicExpressionGrammarAllowedChildSymbolsControl() {
+      InitializeComponent();
+      selectedSymbolicExpressionTreeNodes = new ObservableList<ISymbolicExpressionTreeNode>();
+    }
+
+    private ISymbolicExpressionGrammar grammar;
+    public ISymbolicExpressionGrammar Grammar {
+      get { return grammar; }
+      set {
+        if (grammar != value) {
+          if (grammar != null) DeregisterGrammarEvents();
+          grammar = value;
+          if (grammar != null) RegisterGrammarEvents();
+          OnGrammarChanged();
+        }
+      }
+    }
+
+    private ISymbol symbol;
+    public ISymbol Symbol {
+      get { return symbol; }
+      set {
+        if (symbol != value) {
+          if (value != null && grammar == null) throw new InvalidOperationException("grammar is null");
+          if (value != null && !grammar.ContainsSymbol(value)) throw new ArgumentException("grammar does not contain symbol.");
+          symbol = value;
+          OnSymbolChanged();
+        }
+      }
+    }
+
+    private void RegisterGrammarEvents() {
+      grammar.Changed += new EventHandler(Grammar_Changed);
+    }
+    private void DeregisterGrammarEvents() {
+      grammar.Changed -= new EventHandler(Grammar_Changed);
+    }
+
+    private void Grammar_Changed(object sender, EventArgs e) {
+      if (Grammar == null) return;
+      if (Symbol == null) return;
+      if (Symbol != null && !Grammar.ContainsSymbol(Symbol)) Symbol = null;
+      else BuildAllowedChildSymbolsTree();
+    }
+
+    private void OnGrammarChanged() {
+      if (Grammar == null) {
+        symbolicExpressionTreeChart.Tree = null;
+        Symbol = null;
+      }
+    }
+    private void OnSymbolChanged() {
+      if (Symbol == null) symbolicExpressionTreeChart.Tree = null;
+      else BuildAllowedChildSymbolsTree();
+    }
+
+    private void BuildAllowedChildSymbolsTree() {
+      var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(Symbol));
+
+      symbolicExpressionTreeChart.SuspendRepaint = true;
+      if (Grammar.GetMaximumSubtreeCount(Symbol) > 0) {
+        for (int i = 0; i < Grammar.GetMaximumSubtreeCount(Symbol); i++) {
+          var node = new DummySymbol("Subtree " + i).CreateTreeNode();
+          foreach (var childSymbol in Grammar.GetAllowedChildSymbols(Symbol, i)) {
+            node.AddSubtree(new SymbolicExpressionTreeNode(childSymbol));
+          }
+          tree.Root.AddSubtree(node);
+        }
+      }
+      symbolicExpressionTreeChart.Tree = tree;
+
+      foreach (var subtreeNode in tree.Root.Subtrees) {
+        foreach (var allowedChildNode in subtreeNode.Subtrees) {
+          var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
+          visualLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
+        }
+      }
+
+      for (int i = Grammar.GetMinimumSubtreeCount(symbol); i < Grammar.GetMaximumSubtreeCount(symbol); i++) {
+        var subtreeNode = tree.Root.GetSubtree(i);
+        var visualTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(subtreeNode);
+        visualTreeNode.TextColor = Color.Gray;
+        visualTreeNode.LineColor = Color.LightGray;
+
+        var visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(tree.Root, subtreeNode);
+        visualLine.LineColor = Color.LightGray;
+
+        foreach (var allowedChildNode in subtreeNode.Subtrees) {
+          visualTreeNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(allowedChildNode);
+          visualTreeNode.TextColor = Color.Gray;
+          visualTreeNode.LineColor = Color.LightGray;
+
+          visualLine = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
+          visualLine.LineColor = Color.LightGray;
+        }
+      }
+
+      symbolicExpressionTreeChart.SuspendRepaint = false;
+      symbolicExpressionTreeChart.Repaint();
+      UpdateSelectedSymbolicExpressionTreeNodes();
+    }
+
+    private void UpdateSelectedSymbolicExpressionTreeNodes() {
+      foreach (var node in symbolicExpressionTreeChart.Tree.IterateNodesPrefix()) {
+        var visualNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(node);
+        if (!selectedSymbolicExpressionTreeNodes.Contains(node)) visualNode.FillColor = Color.White;
+        else visualNode.FillColor = Color.LightSteelBlue;
+      }
+      symbolicExpressionTreeChart.Repaint();
+    }
+
+    private void symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
+      if ((Control.ModifierKeys & Keys.Control) == 0)
+        selectedSymbolicExpressionTreeNodes.Clear();
+
+      VisualSymbolicExpressionTreeNode clickedNode = (VisualSymbolicExpressionTreeNode)sender;
+      var selectedNode = clickedNode.SymbolicExpressionTreeNode;
+      if (selectedNode.SubtreeCount == 0) {
+        if (!selectedSymbolicExpressionTreeNodes.Contains(selectedNode))
+          selectedSymbolicExpressionTreeNodes.Add(selectedNode);
+        else
+          selectedSymbolicExpressionTreeNodes.Remove(selectedNode);
+      }
+
+      UpdateSelectedSymbolicExpressionTreeNodes();
+    }
+
+    private void symbolicExpressionTreeChart_KeyDown(object sender, KeyEventArgs e) {
+      if (e.KeyCode == Keys.Delete) {
+        var root = symbolicExpressionTreeChart.Tree.Root;
+        Grammar.StartGrammarManipulation();
+        foreach (var node in selectedSymbolicExpressionTreeNodes) {
+          int argIndex = root.IndexOfSubtree(node.Parent);
+          Grammar.RemoveAllowedChildSymbol(root.Symbol, node.Symbol, argIndex);
+        }
+
+        selectedSymbolicExpressionTreeNodes.Clear();
+        Grammar.FinishedGrammarManipulation();
+      }
+    }
+
+    #region drag & drop operations
+    private bool validDragOperation;
+    private void symbolicExpressionTreeChart_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      var symbol = data as ISymbol;
+      var symbols = data as IEnumerable<ISymbol>;
+      if (symbol != null && !(symbol is IReadOnlySymbol) && Grammar.ContainsSymbol(symbol)) validDragOperation = true;
+      else if (symbols != null && symbols.All(s => !(symbol is IReadOnlySymbol) && Grammar.ContainsSymbol(s))) validDragOperation = true;
+    }
+
+    private void symbolicExpressionTreeChart_DragOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (validDragOperation) {
+        Point coordinates = symbolicExpressionTreeChart.PointToClient(new Point(e.X, e.Y));
+        var visualNode = symbolicExpressionTreeChart.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
+        if (visualNode != null) {
+          var node = visualNode.SymbolicExpressionTreeNode;
+          var root = symbolicExpressionTreeChart.Tree.Root;
+          if (root.Symbol is ProgramRootSymbol) return;
+          if (node == root || node.Parent == root) e.Effect = DragDropEffects.Copy;
+        }
+      }
+    }
+
+    private void symbolicExpressionTreeChart_DragDrop(object sender, DragEventArgs e) {
+      Point coordinates = symbolicExpressionTreeChart.PointToClient(new Point(e.X, e.Y));
+      var node = symbolicExpressionTreeChart.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
+      var root = symbolicExpressionTreeChart.Tree.Root;
+
+      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      var symbol = data as ISymbol;
+      var symbols = data as IEnumerable<ISymbol>;
+
+      if (node.SymbolicExpressionTreeNode == root) {
+        if (symbol != null)
+          Grammar.AddAllowedChildSymbol(root.Symbol, symbol);
+        else if (symbols != null)
+          foreach (var s in symbols) Grammar.AddAllowedChildSymbol(root.Symbol, s);
+      } else {
+        int argumentIndex = root.IndexOfSubtree(node.SymbolicExpressionTreeNode);
+        if (symbol != null)
+          Grammar.AddAllowedChildSymbol(root.Symbol, symbol, argumentIndex);
+        else if (symbols != null)
+          foreach (var s in symbols) Grammar.AddAllowedChildSymbol(root.Symbol, s, argumentIndex);
+      }
+      BuildAllowedChildSymbolsTree();
+    }
+    #endregion
+
+    #region draw and handle root node with buttons to manipulate the subtree count
+    private RectangleF increaseMinimumSubtreeCountRectangle;
+    private RectangleF decreaseMinimumSubtreeCountRectangle;
+    private RectangleF increaseMaximumSubtreeCountRectangle;
+    private RectangleF decreaseMaximumSubtreeCountRectangle;
+    private void allowedChildSymbolsControl_Paint(object sender, PaintEventArgs e) {
+      increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
+      decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
+      increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
+      decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
+
+      if (Grammar == null) return;
+      if (symbolicExpressionTreeChart.Tree == null) return;
+
+      var rootNode = symbolicExpressionTreeChart.Tree.Root;
+      var visualRootNode = symbolicExpressionTreeChart.GetVisualSymbolicExpressionTreeNode(rootNode);
+      var graphics = e.Graphics;
+
+      if (rootNode.Symbol is IReadOnlySymbol) return;
+      if (rootNode.Symbol.MinimumArity == rootNode.Symbol.MaximumArity) return;
+
+      using (Pen pen = new Pen(Color.Black)) {
+        using (Font font = new Font("Times New Roman", 8)) {
+          var stringFormat = new StringFormat();
+          stringFormat.Alignment = StringAlignment.Center;
+          stringFormat.LineAlignment = StringAlignment.Center;
+          int spacing = 5;
+          int size = (visualRootNode.Height - spacing * 3) / 2;
+
+          increaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + spacing, size, size);
+          decreaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + size + 2 * spacing, size, size);
+          increaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + spacing, size, size);
+          decreaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + size + 2 * spacing, size, size);
+
+          pen.Color = Grammar.GetMaximumSubtreeCount(rootNode.Symbol) == Grammar.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
+          graphics.DrawString("+", font, pen.Brush, increaseMinimumSubtreeCountRectangle, stringFormat);
+          graphics.DrawRectangle(pen, Rectangle.Round(increaseMinimumSubtreeCountRectangle));
+          if (pen.Color == Color.LightGray) increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
+
+          pen.Color = Grammar.GetMinimumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MinimumArity ? Color.LightGray : Color.Black;
+          graphics.DrawString("-", font, pen.Brush, decreaseMinimumSubtreeCountRectangle, stringFormat);
+          graphics.DrawRectangle(pen, Rectangle.Round(decreaseMinimumSubtreeCountRectangle));
+          if (pen.Color == Color.LightGray) decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
+
+          pen.Color = Grammar.GetMaximumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MaximumArity ? Color.LightGray : Color.Black;
+          graphics.DrawRectangle(pen, Rectangle.Round(increaseMaximumSubtreeCountRectangle));
+          graphics.DrawString("+", font, pen.Brush, increaseMaximumSubtreeCountRectangle, stringFormat);
+          if (pen.Color == Color.LightGray) increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
+
+          pen.Color = Grammar.GetMaximumSubtreeCount(rootNode.Symbol) == Grammar.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
+          graphics.DrawRectangle(pen, Rectangle.Round(decreaseMaximumSubtreeCountRectangle));
+          graphics.DrawString("-", font, pen.Brush, decreaseMaximumSubtreeCountRectangle, stringFormat);
+          if (pen.Color == Color.LightGray) decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
+        }
+      }
+    }
+
+    private void allowedChildSymbolsControl_MouseDown(object sender, MouseEventArgs e) {
+      if (Grammar == null) return;
+      if (symbolicExpressionTreeChart.Tree == null) return;
+
+      var pointF = new PointF(e.X, e.Y);
+      var rootSymbol = symbolicExpressionTreeChart.Tree.Root.Symbol;
+      int minimumSubtreeCount = Grammar.GetMinimumSubtreeCount(rootSymbol);
+      int maximumSubtreecount = Grammar.GetMaximumSubtreeCount(rootSymbol);
+
+      bool changed = true;
+      if (increaseMinimumSubtreeCountRectangle.Contains(pointF))
+        Grammar.SetSubtreeCount(rootSymbol, minimumSubtreeCount + 1, maximumSubtreecount);
+      else if (decreaseMinimumSubtreeCountRectangle.Contains(pointF))
+        Grammar.SetSubtreeCount(rootSymbol, minimumSubtreeCount - 1, maximumSubtreecount);
+      else if (increaseMaximumSubtreeCountRectangle.Contains(pointF))
+        Grammar.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount + 1);
+      else if (decreaseMaximumSubtreeCountRectangle.Contains(pointF))
+        Grammar.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount - 1);
+      else
+        changed = false;
+
+      if (changed) BuildAllowedChildSymbolsTree();
+    }
+    #endregion
+
+  }
+
+  [NonDiscoverableType]
+  internal class DummySymbol : 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; }
+    }
+
+    public DummySymbol(DummySymbol original, Cloner cloner) : base(original, cloner) { }
+    public DummySymbol(string name) : base(name, "DummySymbol for views") { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new DummySymbol(this, cloner); }
+  }
+}
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 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.Designer.cs	(revision 6415)
@@ -28,11 +28,13 @@
       this.grpSymbols = new System.Windows.Forms.GroupBox();
       this.splitContainer1 = new System.Windows.Forms.SplitContainer();
+      this.copyButton = new System.Windows.Forms.Button();
       this.showDetailsCheckBox = new System.Windows.Forms.CheckBox();
       this.removeButton = new System.Windows.Forms.Button();
       this.addButton = new System.Windows.Forms.Button();
-      this.symbolsTreeView = new System.Windows.Forms.TreeView();
+      this.symbolsTreeView = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.CheckBoxTreeView();
       this.imageList = new System.Windows.Forms.ImageList(this.components);
       this.splitContainer2 = new System.Windows.Forms.SplitContainer();
-      this.allowedChildSymbolsControl = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart();
+      this.allowedChildSymbolsControl = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionGrammarAllowedChildSymbolsControl();
+      this.symbolDetailsGroupBox = new System.Windows.Forms.GroupBox();
       this.symbolDetailsViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
       ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
@@ -46,4 +48,5 @@
       this.splitContainer2.Panel2.SuspendLayout();
       this.splitContainer2.SuspendLayout();
+      this.symbolDetailsGroupBox.SuspendLayout();
       this.SuspendLayout();
       // 
@@ -79,4 +82,5 @@
       // splitContainer1.Panel1
       // 
+      this.splitContainer1.Panel1.Controls.Add(this.copyButton);
       this.splitContainer1.Panel1.Controls.Add(this.showDetailsCheckBox);
       this.splitContainer1.Panel1.Controls.Add(this.removeButton);
@@ -91,4 +95,16 @@
       this.splitContainer1.TabIndex = 0;
       // 
+      // copyButton
+      // 
+      this.copyButton.Enabled = false;
+      this.copyButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Copy;
+      this.copyButton.Location = new System.Drawing.Point(33, 3);
+      this.copyButton.Name = "copyButton";
+      this.copyButton.Size = new System.Drawing.Size(24, 24);
+      this.copyButton.TabIndex = 8;
+      this.toolTip.SetToolTip(this.copyButton, "Copy Symbol");
+      this.copyButton.UseVisualStyleBackColor = true;
+      this.copyButton.Click += new System.EventHandler(this.copyButton_Click);
+      // 
       // showDetailsCheckBox
       // 
@@ -97,5 +113,5 @@
       this.showDetailsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
       this.showDetailsCheckBox.Image = HeuristicLab.Common.Resources.VSImageLibrary.Properties;
-      this.showDetailsCheckBox.Location = new System.Drawing.Point(63, 3);
+      this.showDetailsCheckBox.Location = new System.Drawing.Point(93, 3);
       this.showDetailsCheckBox.Name = "showDetailsCheckBox";
       this.showDetailsCheckBox.Size = new System.Drawing.Size(24, 24);
@@ -109,9 +125,9 @@
       this.removeButton.Enabled = false;
       this.removeButton.Image = HeuristicLab.Common.Resources.VSImageLibrary.Remove;
-      this.removeButton.Location = new System.Drawing.Point(33, 3);
+      this.removeButton.Location = new System.Drawing.Point(63, 3);
       this.removeButton.Name = "removeButton";
       this.removeButton.Size = new System.Drawing.Size(24, 24);
       this.removeButton.TabIndex = 6;
-      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      this.toolTip.SetToolTip(this.removeButton, "Remove Symbol");
       this.removeButton.UseVisualStyleBackColor = true;
       this.removeButton.Click += new System.EventHandler(this.removeButton_Click);
@@ -124,5 +140,5 @@
       this.addButton.Size = new System.Drawing.Size(24, 24);
       this.addButton.TabIndex = 5;
-      this.toolTip.SetToolTip(this.addButton, "Add");
+      this.toolTip.SetToolTip(this.addButton, "Add Symbol");
       this.addButton.UseVisualStyleBackColor = true;
       this.addButton.Click += new System.EventHandler(this.addButton_Click);
@@ -130,8 +146,10 @@
       // symbolsTreeView
       // 
+      this.symbolsTreeView.AllowDrop = true;
       this.symbolsTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
             | System.Windows.Forms.AnchorStyles.Left)
             | System.Windows.Forms.AnchorStyles.Right)));
       this.symbolsTreeView.CheckBoxes = true;
+      this.symbolsTreeView.HideSelection = false;
       this.symbolsTreeView.ImageIndex = 0;
       this.symbolsTreeView.ImageList = this.imageList;
@@ -144,4 +162,7 @@
       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);
       // 
       // imageList
@@ -164,5 +185,5 @@
       // splitContainer2.Panel2
       // 
-      this.splitContainer2.Panel2.Controls.Add(this.symbolDetailsViewHost);
+      this.splitContainer2.Panel2.Controls.Add(this.symbolDetailsGroupBox);
       this.splitContainer2.Size = new System.Drawing.Size(568, 359);
       this.splitContainer2.SplitterDistance = 165;
@@ -172,21 +193,22 @@
       // 
       this.allowedChildSymbolsControl.AllowDrop = true;
-      this.allowedChildSymbolsControl.BackgroundColor = System.Drawing.Color.White;
       this.allowedChildSymbolsControl.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.allowedChildSymbolsControl.LineColor = System.Drawing.Color.Black;
+      this.allowedChildSymbolsControl.Grammar = null;
       this.allowedChildSymbolsControl.Location = new System.Drawing.Point(0, 0);
       this.allowedChildSymbolsControl.Name = "allowedChildSymbolsControl";
       this.allowedChildSymbolsControl.Size = new System.Drawing.Size(568, 165);
-      this.allowedChildSymbolsControl.Spacing = 5;
+      this.allowedChildSymbolsControl.Symbol = null;
       this.allowedChildSymbolsControl.TabIndex = 0;
-      this.allowedChildSymbolsControl.TextFont = new System.Drawing.Font("Times New Roman", 8F);
-      this.allowedChildSymbolsControl.Tree = null;
-      this.allowedChildSymbolsControl.SymbolicExpressionTreeNodeClicked += new System.Windows.Forms.MouseEventHandler(this.symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked);
-      this.allowedChildSymbolsControl.DragDrop += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragDrop);
-      this.allowedChildSymbolsControl.DragEnter += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragEnter);
-      this.allowedChildSymbolsControl.DragOver += new System.Windows.Forms.DragEventHandler(this.symbolicExpressionTreeChart_DragOver);
-      this.allowedChildSymbolsControl.Paint += new System.Windows.Forms.PaintEventHandler(this.allowedChildSymbolsControl_Paint);
-      this.allowedChildSymbolsControl.KeyDown += new System.Windows.Forms.KeyEventHandler(this.symbolicExpressionTreeChart_KeyDown);
-      this.allowedChildSymbolsControl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.allowedChildSymbolsControl_MouseDown);
+      // 
+      // symbolDetailsGroupBox
+      // 
+      this.symbolDetailsGroupBox.Controls.Add(this.symbolDetailsViewHost);
+      this.symbolDetailsGroupBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.symbolDetailsGroupBox.Location = new System.Drawing.Point(0, 0);
+      this.symbolDetailsGroupBox.Name = "symbolDetailsGroupBox";
+      this.symbolDetailsGroupBox.Size = new System.Drawing.Size(568, 190);
+      this.symbolDetailsGroupBox.TabIndex = 1;
+      this.symbolDetailsGroupBox.TabStop = false;
+      this.symbolDetailsGroupBox.Text = "Symbol Details";
       // 
       // symbolDetailsViewHost
@@ -196,9 +218,9 @@
       this.symbolDetailsViewHost.Dock = System.Windows.Forms.DockStyle.Fill;
       this.symbolDetailsViewHost.Enabled = false;
-      this.symbolDetailsViewHost.Location = new System.Drawing.Point(0, 0);
+      this.symbolDetailsViewHost.Location = new System.Drawing.Point(3, 16);
       this.symbolDetailsViewHost.Name = "symbolDetailsViewHost";
       this.symbolDetailsViewHost.ReadOnly = false;
-      this.symbolDetailsViewHost.Size = new System.Drawing.Size(568, 190);
-      this.symbolDetailsViewHost.TabIndex = 0;
+      this.symbolDetailsViewHost.Size = new System.Drawing.Size(562, 171);
+      this.symbolDetailsViewHost.TabIndex = 1;
       this.symbolDetailsViewHost.ViewsLabelVisible = true;
       this.symbolDetailsViewHost.ViewType = null;
@@ -225,4 +247,5 @@
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer2)).EndInit();
       this.splitContainer2.ResumeLayout(false);
+      this.symbolDetailsGroupBox.ResumeLayout(false);
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -233,12 +256,14 @@
     private System.Windows.Forms.GroupBox grpSymbols;
     private System.Windows.Forms.SplitContainer splitContainer1;
-    private System.Windows.Forms.TreeView symbolsTreeView;
+    private CheckBoxTreeView symbolsTreeView;
     private System.Windows.Forms.SplitContainer splitContainer2;
-    private SymbolicExpressionTreeChart allowedChildSymbolsControl;
-    private MainForm.WindowsForms.ViewHost symbolDetailsViewHost;
     private System.Windows.Forms.ImageList imageList;
     protected System.Windows.Forms.CheckBox showDetailsCheckBox;
     protected System.Windows.Forms.Button removeButton;
     protected System.Windows.Forms.Button addButton;
+    private System.Windows.Forms.GroupBox symbolDetailsGroupBox;
+    private MainForm.WindowsForms.ViewHost symbolDetailsViewHost;
+    protected System.Windows.Forms.Button copyButton;
+    private SymbolicExpressionGrammarAllowedChildSymbolsControl allowedChildSymbolsControl;
   }
 }
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 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views/3.4/SymbolicExpressionGrammarEditorView.cs	(revision 6415)
@@ -25,5 +25,4 @@
 using System.Linq;
 using System.Windows.Forms;
-using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core.Views;
@@ -35,9 +34,6 @@
   [Content(typeof(ISymbolicExpressionGrammar), false)]
   public partial class SymbolicExpressionGrammarEditorView : NamedItemView {
-    private ObservableList<ISymbolicExpressionTreeNode> selectedSymbolicExpressionTreeNodes;
-
     public SymbolicExpressionGrammarEditorView() {
       InitializeComponent();
-      selectedSymbolicExpressionTreeNodes = new ObservableList<ISymbolicExpressionTreeNode>();
     }
 
@@ -56,4 +52,27 @@
       get { return (ISymbolicExpressionGrammar)base.Content; }
       set { base.Content = value; }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      addButton.Enabled = Content != null;
+      removeButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
+      copyButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        symbolsTreeView.Nodes.Clear();
+        UpdateSymbolsTreeView();
+        symbolsTreeView.ExpandAll();
+        allowedChildSymbolsControl.Grammar = Content;
+        allowedChildSymbolsControl.Symbol = null;
+        symbolDetailsViewHost.Content = null;
+      } else {
+        symbolsTreeView.Nodes.Clear();
+        allowedChildSymbolsControl.Grammar = null;
+        symbolDetailsViewHost.Content = null;
+      }
     }
 
@@ -79,7 +98,9 @@
         symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
 
-      RebuildSymbolsTreeView();
+      allowedChildSymbolsControl.Grammar = Content;
+
+      UpdateSymbolsTreeView();
       if (symbol != null && Content.ContainsSymbol(symbol)) {
-        BuildAllowedChildSymbolsTree(symbol);
+        allowedChildSymbolsControl.Symbol = symbol;
         symbolDetailsViewHost.Content = symbol;
         symbolsTreeView.SelectedNode = IterateSymbolTreeNodes().Where(n => n.Tag == symbol).ToList().FirstOrDefault();
@@ -88,29 +109,30 @@
     #endregion
 
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-    }
-
-    protected override void OnContentChanged() {
-      base.OnContentChanged();
-      if (Content != null) {
-        RebuildSymbolsTreeView();
-        allowedChildSymbolsControl.Tree = null;
-        symbolDetailsViewHost.Content = null;
-      } else {
-        symbolsTreeView.Nodes.Clear();
-        allowedChildSymbolsControl.Tree = null;
-        symbolDetailsViewHost.Content = null;
-      }
+    private void UpdateSymbolsTreeView() {
+      var symbols = Content.Symbols.ToList();
+      foreach (var treeNode in IterateSymbolTreeNodes().ToList()) {
+        var symbol = treeNode.Tag as ISymbol;
+        if (!symbols.Contains(symbol))
+          treeNode.Remove();
+      }
+
+      var groupSymbols = symbols.OfType<GroupSymbol>().ToList();
+      var topLevelSymbols = Content.Symbols.Where(s => !groupSymbols.Any(g => g.Symbols.Contains(s)));
+      AddChildTreeNodes(symbolsTreeView.Nodes, topLevelSymbols);
+
+      RebuildImageList();
     }
 
     private void AddChildTreeNodes(TreeNodeCollection collection, IEnumerable<ISymbol> symbols) {
       foreach (ISymbol symbol in symbols) {
-        var node = new TreeNode();
-        node.Name = symbol.Name;
-        node.Text = symbol.Name;
-        node.Tag = symbol;
-        node.Checked = symbol.Enabled;
-        collection.Add(node);
+        TreeNode node = collection.Cast<TreeNode>().Where(n => n.Tag == symbol).FirstOrDefault();
+        if (node == null) {
+          node = new TreeNode();
+          node.Name = symbol.Name;
+          node.Text = symbol.Name;
+          node.Tag = symbol;
+          node.Checked = symbol.Enabled;
+          collection.Add(node);
+        }
         var groupSymbol = symbol as GroupSymbol;
         if (groupSymbol != null) AddChildTreeNodes(node.Nodes, groupSymbol.Symbols);
@@ -122,13 +144,14 @@
         var symbol = (ISymbol)e.Node.Tag;
         symbolDetailsViewHost.Content = symbol;
-        selectedSymbolicExpressionTreeNodes.Clear();
-        BuildAllowedChildSymbolsTree(symbol);
+        allowedChildSymbolsControl.Symbol = symbol;
       }
       removeButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
+      copyButton.Enabled = symbolsTreeView.SelectedNode != null && !(symbolsTreeView.SelectedNode.Tag is IReadOnlySymbol);
     }
 
     private void symbolsTreeView_AfterCheck(object sender, TreeViewEventArgs e) {
       if (e.Action != TreeViewAction.Unknown) {
-        DeregisterContentEvents();
+        Content.StartGrammarManipulation();
+        allowedChildSymbolsControl.Symbol = null;
         var symbol = (ISymbol)e.Node.Tag;
         symbol.Enabled = e.Node.Checked;
@@ -138,222 +161,70 @@
         if (symbolsTreeView.SelectedNode != null) {
           symbol = (ISymbol)symbolsTreeView.SelectedNode.Tag;
-          selectedSymbolicExpressionTreeNodes.Clear();
-          BuildAllowedChildSymbolsTree(symbol);
-        }
-        RegisterContentEvents();
-      }
-    }
-
-    private void RebuildSymbolsTreeView() {
-      symbolsTreeView.Nodes.Clear();
-      var symbols = Content.Symbols.ToList();
-      var groupSymbols = symbols.OfType<GroupSymbol>().ToList();
-      var topLevelSymbols = Content.Symbols.Where(s => !groupSymbols.Any(g => g.Symbols.Contains(s)));
-      AddChildTreeNodes(symbolsTreeView.Nodes, topLevelSymbols);
-
-      RebuildImageList();
-      symbolsTreeView.ExpandAll();
-    }
-
-    private void BuildAllowedChildSymbolsTree(ISymbol symbol) {
-      var tree = new SymbolicExpressionTree(new SymbolicExpressionTreeNode(symbol));
-
-      allowedChildSymbolsControl.SuspendRepaint = true;
-      if (Content.GetMaximumSubtreeCount(symbol) > 0) {
-        for (int i = 0; i < Content.GetMaximumSubtreeCount(symbol); i++) {
-          var node = new DummySymbol("Subtree " + i).CreateTreeNode();
-          foreach (var childSymbol in Content.GetAllowedChildSymbols(symbol, i)) {
-            node.AddSubtree(new SymbolicExpressionTreeNode(childSymbol));
-          }
-          tree.Root.AddSubtree(node);
-        }
-      }
-      allowedChildSymbolsControl.Tree = tree;
-
-      foreach (var subtreeNode in tree.Root.Subtrees) {
-        foreach (var allowedChildNode in subtreeNode.Subtrees) {
-          var visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
-          visualLine.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
-        }
-      }
-
-      for (int i = Content.GetMinimumSubtreeCount(symbol); i < Content.GetMaximumSubtreeCount(symbol); i++) {
-        var subtreeNode = tree.Root.GetSubtree(i);
-        var visualTreeNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(subtreeNode);
-        visualTreeNode.TextColor = Color.Gray;
-        visualTreeNode.LineColor = Color.LightGray;
-
-        var visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(tree.Root, subtreeNode);
-        visualLine.LineColor = Color.LightGray;
-
-        foreach (var allowedChildNode in subtreeNode.Subtrees) {
-          visualTreeNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(allowedChildNode);
-          visualTreeNode.TextColor = Color.Gray;
-          visualTreeNode.LineColor = Color.LightGray;
-
-          visualLine = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNodeConnection(subtreeNode, allowedChildNode);
-          visualLine.LineColor = Color.LightGray;
-        }
-      }
-
-      allowedChildSymbolsControl.SuspendRepaint = false;
-      allowedChildSymbolsControl.Repaint();
-      UpdateSelectedSymbolicExpressionTreeNodes();
-    }
-
-    private void symbolicExpressionTreeChart_SymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
-      if ((Control.ModifierKeys & Keys.Control) == 0)
-        selectedSymbolicExpressionTreeNodes.Clear();
-
-      VisualSymbolicExpressionTreeNode clickedNode = (VisualSymbolicExpressionTreeNode)sender;
-      var selectedNode = clickedNode.SymbolicExpressionTreeNode;
-      if (selectedNode.SubtreeCount == 0) {
-        if (!selectedSymbolicExpressionTreeNodes.Contains(selectedNode))
-          selectedSymbolicExpressionTreeNodes.Add(selectedNode);
-        else
-          selectedSymbolicExpressionTreeNodes.Remove(selectedNode);
-      }
-
-      UpdateSelectedSymbolicExpressionTreeNodes();
-    }
-
-    private void symbolicExpressionTreeChart_KeyDown(object sender, KeyEventArgs e) {
-      if (e.KeyCode == Keys.Delete) {
-        DeregisterContentEvents();
-        var root = allowedChildSymbolsControl.Tree.Root;
-        foreach (var node in selectedSymbolicExpressionTreeNodes) {
-          int argIndex = root.IndexOfSubtree(node.Parent);
-          Content.RemoveAllowedChildSymbol(root.Symbol, node.Symbol, argIndex);
-        }
-        RegisterContentEvents();
-        selectedSymbolicExpressionTreeNodes.Clear();
-        BuildAllowedChildSymbolsTree(root.Symbol);
-      }
-    }
-
+          allowedChildSymbolsControl.Symbol = symbol;
+        }
+        Content.FinishedGrammarManipulation();
+      }
+    }
+
+    #region drag & drop operations
+    private GroupSymbol parentOfDraggedSymbol;
     private void symbolsTreeView_ItemDrag(object sender, ItemDragEventArgs e) {
       if (!Locked) {
-        DataObject data = new DataObject();
-        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, ((TreeNode)e.Item).Tag);
-        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Link);
-      }
-    }
+        var treeNode = e.Item as TreeNode;
+        if (treeNode.Parent != null) parentOfDraggedSymbol = treeNode.Parent.Tag as GroupSymbol;
+        var data = new DataObject();
+        data.SetData(HeuristicLab.Common.Constants.DragDropDataFormat, treeNode.Tag);
+        validDragOperation = true;
+        DoDragDrop(data, DragDropEffects.Copy | DragDropEffects.Move);
+      }
+    }
+
 
     private bool validDragOperation;
-    private void symbolicExpressionTreeChart_DragEnter(object sender, DragEventArgs e) {
+    private void symbolsTreeView_DragEnter(object sender, DragEventArgs e) {
       validDragOperation = false;
+      if (Content == null) return;
+
       var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
       var symbol = data as ISymbol;
-      var symbols = data as IEnumerable<ISymbol>;
-      if (symbol != null && !(symbol is IReadOnlySymbol) && Content.ContainsSymbol(symbol)) validDragOperation = true;
-      else if (symbols != null && symbols.All(s => !(symbol is IReadOnlySymbol) && Content.ContainsSymbol(s))) validDragOperation = true;
-    }
-
-    private void symbolicExpressionTreeChart_DragOver(object sender, DragEventArgs e) {
+      if (symbol != null && !(symbol is IReadOnlySymbol)) validDragOperation = true;
+    }
+    private void symbolsTreeView_DragOver(object sender, DragEventArgs e) {
       e.Effect = DragDropEffects.None;
       if (validDragOperation) {
-        Point coordinates = allowedChildSymbolsControl.PointToClient(new Point(e.X, e.Y));
-        var visualNode = allowedChildSymbolsControl.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
-        if (visualNode != null) {
-          var node = visualNode.SymbolicExpressionTreeNode;
-          var root = allowedChildSymbolsControl.Tree.Root;
-          if (root.Symbol is ProgramRootSymbol) return;
-          if (node == root || node.Parent == root) e.Effect = DragDropEffects.Copy;
-        }
-      }
-    }
-
-    private void symbolicExpressionTreeChart_DragDrop(object sender, DragEventArgs e) {
-      Point coordinates = allowedChildSymbolsControl.PointToClient(new Point(e.X, e.Y));
-      var node = allowedChildSymbolsControl.FindVisualSymbolicExpressionTreeNodeAt(coordinates.X, coordinates.Y);
-      var root = allowedChildSymbolsControl.Tree.Root;
-
-      var data = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
-      var symbol = data as ISymbol;
-      var symbols = data as IEnumerable<ISymbol>;
-
-      DeregisterContentEvents();
-      if (node.SymbolicExpressionTreeNode == root) {
-        if (symbol != null)
-          Content.AddAllowedChildSymbol(root.Symbol, symbol);
-        else if (symbols != null)
-          foreach (var s in symbols) Content.AddAllowedChildSymbol(root.Symbol, s);
-      } else {
-        int argumentIndex = root.IndexOfSubtree(node.SymbolicExpressionTreeNode);
-        if (symbol != null)
-          Content.AddAllowedChildSymbol(root.Symbol, symbol, argumentIndex);
-        else if (symbols != null)
-          foreach (var s in symbols) Content.AddAllowedChildSymbol(root.Symbol, s, argumentIndex);
-      }
-      RegisterContentEvents();
-      BuildAllowedChildSymbolsTree(root.Symbol);
-    }
-
-    private void UpdateSelectedSymbolicExpressionTreeNodes() {
-      foreach (var node in allowedChildSymbolsControl.Tree.IterateNodesPrefix()) {
-        var visualNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(node);
-        if (!selectedSymbolicExpressionTreeNodes.Contains(node)) visualNode.FillColor = Color.White;
-        else visualNode.FillColor = Color.LightSteelBlue;
-
-      }
-      allowedChildSymbolsControl.Repaint();
-    }
-
-    private RectangleF increaseMinimumSubtreeCountRectangle;
-    private RectangleF decreaseMinimumSubtreeCountRectangle;
-    private RectangleF increaseMaximumSubtreeCountRectangle;
-    private RectangleF decreaseMaximumSubtreeCountRectangle;
-    private void allowedChildSymbolsControl_Paint(object sender, PaintEventArgs e) {
-      increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
-      decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
-      increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
-      decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
-
-      if (Content == null) return;
-      if (allowedChildSymbolsControl.Tree == null) return;
-
-      var rootNode = allowedChildSymbolsControl.Tree.Root;
-      var visualRootNode = allowedChildSymbolsControl.GetVisualSymbolicExpressionTreeNode(rootNode);
-      var graphics = e.Graphics;
-
-      if (rootNode.Symbol is IReadOnlySymbol) return;
-      if (rootNode.Symbol.MinimumArity == rootNode.Symbol.MaximumArity) return;
-
-      using (Pen pen = new Pen(Color.Black)) {
-        using (Font font = new Font("Times New Roman", 8)) {
-          var stringFormat = new StringFormat();
-          stringFormat.Alignment = StringAlignment.Center;
-          stringFormat.LineAlignment = StringAlignment.Center;
-          int spacing = 5;
-          int size = (visualRootNode.Height - spacing * 3) / 2;
-
-          increaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + spacing, size, size);
-          decreaseMinimumSubtreeCountRectangle = new RectangleF(visualRootNode.X - spacing - size, visualRootNode.Y + size + 2 * spacing, size, size);
-          increaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + spacing, size, size);
-          decreaseMaximumSubtreeCountRectangle = new RectangleF(visualRootNode.X + visualRootNode.Width + spacing, visualRootNode.Y + size + 2 * spacing, size, size);
-
-          pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == Content.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
-          graphics.DrawString("+", font, pen.Brush, increaseMinimumSubtreeCountRectangle, stringFormat);
-          graphics.DrawRectangle(pen, Rectangle.Round(increaseMinimumSubtreeCountRectangle));
-          if (pen.Color == Color.LightGray) increaseMinimumSubtreeCountRectangle = RectangleF.Empty;
-
-          pen.Color = Content.GetMinimumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MinimumArity ? Color.LightGray : Color.Black;
-          graphics.DrawString("-", font, pen.Brush, decreaseMinimumSubtreeCountRectangle, stringFormat);
-          graphics.DrawRectangle(pen, Rectangle.Round(decreaseMinimumSubtreeCountRectangle));
-          if (pen.Color == Color.LightGray) decreaseMinimumSubtreeCountRectangle = RectangleF.Empty;
-
-          pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == rootNode.Symbol.MaximumArity ? Color.LightGray : Color.Black;
-          graphics.DrawRectangle(pen, Rectangle.Round(increaseMaximumSubtreeCountRectangle));
-          graphics.DrawString("+", font, pen.Brush, increaseMaximumSubtreeCountRectangle, stringFormat);
-          if (pen.Color == Color.LightGray) increaseMaximumSubtreeCountRectangle = RectangleF.Empty;
-
-          pen.Color = Content.GetMaximumSubtreeCount(rootNode.Symbol) == Content.GetMinimumSubtreeCount(rootNode.Symbol) ? Color.LightGray : Color.Black;
-          graphics.DrawRectangle(pen, Rectangle.Round(decreaseMaximumSubtreeCountRectangle));
-          graphics.DrawString("-", font, pen.Brush, decreaseMaximumSubtreeCountRectangle, stringFormat);
-          if (pen.Color == Color.LightGray) decreaseMaximumSubtreeCountRectangle = RectangleF.Empty;
-        }
-      }
-    }
-
+        GroupSymbol groupSymbol = null;
+        Point mouse = symbolsTreeView.PointToClient(new Point(e.X, e.Y));
+        TreeNode node = symbolsTreeView.GetNodeAt(mouse);
+        if (node != null) groupSymbol = node.Tag as GroupSymbol;
+        if (node != null && groupSymbol == null) groupSymbol = node.Parent.Tag as GroupSymbol;
+        var symbol = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        if (symbol == groupSymbol) return;
+
+        if (e.AllowedEffect.HasFlag(DragDropEffects.Copy)) e.Effect = DragDropEffects.Copy;
+      }
+    }
+    private void symbolsTreeView_DragDrop(object sender, DragEventArgs e) {
+      var symbol = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as ISymbol;
+
+      GroupSymbol groupSymbol = null;
+      Point mouse = symbolsTreeView.PointToClient(new Point(e.X, e.Y));
+      TreeNode node = symbolsTreeView.GetNodeAt(mouse);
+      if (node != null) groupSymbol = node.Tag as GroupSymbol;
+      if (node != null && groupSymbol == null) groupSymbol = node.Parent.Tag as GroupSymbol;
+
+      Content.StartGrammarManipulation();
+      Cloner cloner = new Cloner();
+      var clonedSymbol = cloner.Clone(symbol);
+      ChangeDuplicateSymbolNames(clonedSymbol);
+
+      if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(clonedSymbol);
+      else Content.AddSymbol(clonedSymbol);
+
+      UpdateGrammerConstraintsForClonedSymbol(symbol, cloner);
+      Content.FinishedGrammarManipulation();
+    }
+    #endregion
+
+    #region button events
     private TypeSelectorDialog typeSelectorDialog;
     private void addButton_Click(object sender, EventArgs e) {
@@ -367,20 +238,11 @@
         try {
           ISymbol symbol = (ISymbol)typeSelectorDialog.TypeSelector.CreateInstanceOfSelectedType();
-          var originalSymbolName = symbol.Name;
-          int i = 1;
-          while (Content.ContainsSymbol(symbol)) {
-            symbol.Name = originalSymbolName + i;
-            i++;
-          }
+          ChangeDuplicateSymbolNames(symbol);
 
           var selectedNode = symbolsTreeView.SelectedNode;
-          GroupSymbol groupSymbol = null;
-          while (selectedNode != null) {
-            groupSymbol = selectedNode.Tag as GroupSymbol;
-            if (groupSymbol != null && Content.ContainsSymbol(groupSymbol)) break;
-            selectedNode = selectedNode.Parent;
-          }
-
-          if (groupSymbol != null && Content.ContainsSymbol(groupSymbol)) groupSymbol.SymbolsCollection.Add(symbol);
+          GroupSymbol groupSymbol = selectedNode.Tag as GroupSymbol;
+          if (groupSymbol == null && selectedNode.Parent != null) groupSymbol = selectedNode.Parent.Tag as GroupSymbol;
+
+          if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(symbol);
           else Content.AddSymbol(symbol);
         }
@@ -391,11 +253,33 @@
     }
 
+    private void copyButton_Click(object sender, EventArgs e) {
+      var symbol = symbolsTreeView.SelectedNode.Tag as ISymbol;
+      if (symbol != null && !(symbol is IReadOnlySymbol)) {
+        allowedChildSymbolsControl.Symbol = null;
+        symbolDetailsViewHost.Content = null;
+
+        Content.StartGrammarManipulation();
+        Cloner cloner = new Cloner();
+        var clonedSymbol = cloner.Clone(symbol);
+        ChangeDuplicateSymbolNames(clonedSymbol);
+
+        GroupSymbol groupSymbol = null;
+        if (symbolsTreeView.SelectedNode.Parent != null) groupSymbol = symbolsTreeView.SelectedNode.Parent.Tag as GroupSymbol;
+
+        if (groupSymbol != null) groupSymbol.SymbolsCollection.Add(clonedSymbol);
+        else Content.AddSymbol(clonedSymbol);
+
+        UpdateGrammerConstraintsForClonedSymbol(symbol, cloner);
+        Content.FinishedGrammarManipulation();
+      }
+    }
+
     private void removeButton_Click(object sender, EventArgs e) {
       var symbol = symbolsTreeView.SelectedNode.Tag as ISymbol;
-      if (symbol != null && !(symbol is IReadOnlySymbol))
+      if (symbol != null && !(symbol is IReadOnlySymbol)) {
         Content.RemoveSymbol(symbol);
-      removeButton.Enabled = false;
-      allowedChildSymbolsControl.Tree = null;
-      symbolDetailsViewHost.Content = null;
+        allowedChildSymbolsControl.Symbol = null;
+        symbolDetailsViewHost.Content = null;
+      }
     }
 
@@ -403,6 +287,39 @@
       splitContainer1.Panel2Collapsed = !showDetailsCheckBox.Checked;
     }
+    #endregion
 
     #region helpers
+    private void UpdateGrammerConstraintsForClonedSymbol(ISymbol symbol, Cloner cloner) {
+      foreach (var s in symbol.Flatten().Where(x => !(x is GroupSymbol))) {
+        if (!cloner.ClonedObjectRegistered(s)) throw new InvalidOperationException();
+        var clone = cloner.Clone(s);
+        Content.SetSubtreeCount(clone, Content.GetMinimumSubtreeCount(s), Content.GetMaximumSubtreeCount(s));
+        foreach (var childSymbol in Content.GetAllowedChildSymbols(s)) {
+          var newChildSymbol = childSymbol;
+          if (cloner.ClonedObjectRegistered(childSymbol)) newChildSymbol = cloner.Clone(childSymbol);
+          Content.AddAllowedChildSymbol(clone, newChildSymbol);
+        }
+        for (int i = 0; i < Content.GetMaximumSubtreeCount(s); i++) {
+          foreach (var childSymbol in Content.GetAllowedChildSymbols(s, i)) {
+            var newChildSymbol = childSymbol;
+            if (cloner.ClonedObjectRegistered(childSymbol)) newChildSymbol = cloner.Clone(childSymbol);
+            Content.AddAllowedChildSymbol(clone, newChildSymbol, i);
+          }
+        }
+      }
+    }
+
+
+    private void ChangeDuplicateSymbolNames(ISymbol symbol) {
+      foreach (var s in symbol.Flatten()) {
+        var originalSymbolName = s.Name;
+        int i = 1;
+        while (Content.ContainsSymbol(s)) {
+          s.Name = originalSymbolName + i;
+          i++;
+        }
+      }
+    }
+
     private IEnumerable<TreeNode> IterateSymbolTreeNodes(TreeNode node = null) {
       TreeNodeCollection nodes;
@@ -428,47 +345,12 @@
     }
     #endregion
-
-    private void allowedChildSymbolsControl_MouseDown(object sender, MouseEventArgs e) {
-      if (Content == null) return;
-      if (allowedChildSymbolsControl.Tree == null) return;
-
-      var pointF = new PointF(e.X, e.Y);
-      var rootSymbol = allowedChildSymbolsControl.Tree.Root.Symbol;
-      int minimumSubtreeCount = Content.GetMinimumSubtreeCount(rootSymbol);
-      int maximumSubtreecount = Content.GetMaximumSubtreeCount(rootSymbol);
-
-      bool changed = true;
-      DeregisterContentEvents();
-      if (increaseMinimumSubtreeCountRectangle.Contains(pointF))
-        Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount + 1, maximumSubtreecount);
-      else if (decreaseMinimumSubtreeCountRectangle.Contains(pointF))
-        Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount - 1, maximumSubtreecount);
-      else if (increaseMaximumSubtreeCountRectangle.Contains(pointF))
-        Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount + 1);
-      else if (decreaseMaximumSubtreeCountRectangle.Contains(pointF))
-        Content.SetSubtreeCount(rootSymbol, minimumSubtreeCount, maximumSubtreecount - 1);
-      else
-        changed = false;
-
-      if (changed) BuildAllowedChildSymbolsTree(rootSymbol);
-      RegisterContentEvents();
-    }
   }
 
-  [NonDiscoverableType]
-  internal class DummySymbol : 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; }
-    }
-
-    public DummySymbol(DummySymbol original, Cloner cloner) : base(original, cloner) { }
-    public DummySymbol(string name) : base(name, "DummySymbol for views") { }
-    public override IDeepCloneable Clone(Cloner cloner) { return new DummySymbol(this, cloner); }
+  //this class is necessary to prevent double clicks which do not fire the checkbox checked event
+  internal class CheckBoxTreeView : TreeView {
+    protected override void WndProc(ref Message m) {
+      // Suppress WM_LBUTTONDBLCLK
+      if (m.Msg == 0x203) { m.Result = IntPtr.Zero; } else base.WndProc(ref m);
+    }
   }
 }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/ISymbolicExpressionGrammar.cs	(revision 6415)
@@ -45,4 +45,7 @@
 
     void SetSubtreeCount(ISymbol symbol, int minimumSubtreeCount, int maximumSubtreeCount);
+
+    void StartGrammarManipulation();
+    void FinishedGrammarManipulation();
   }
 }
Index: branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammar.cs	(revision 6415)
@@ -198,4 +198,17 @@
       base.SetSubtreeCount(symbol, minimumSubtreeCount, maximumSubtreeCount);
     }
+
+    private bool suppressEvents = false;
+    void ISymbolicExpressionGrammar.StartGrammarManipulation() {
+      suppressEvents = true;
+    }
+    void ISymbolicExpressionGrammar.FinishedGrammarManipulation() {
+      suppressEvents = false;
+      OnChanged();
+    }
+
+    protected override void OnChanged() {
+      if (!suppressEvents) base.OnChanged();
+    }
     #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 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionGrammarBase.cs	(revision 6415)
@@ -64,5 +64,5 @@
     #endregion
 
-    protected bool suppressEvents;
+    private bool suppressEvents;
     protected Dictionary<string, ISymbol> symbols;
     protected Dictionary<string, Tuple<int, int>> symbolSubtreeCount;
Index: branches/GP.Grammar.Editor/HeuristicLab.PluginInfrastructure/3.3/Advanced/DeploymentService/ServiceClients.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.PluginInfrastructure/3.3/Advanced/DeploymentService/ServiceClients.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.PluginInfrastructure/3.3/Advanced/DeploymentService/ServiceClients.cs	(revision 6415)
@@ -2,5 +2,5 @@
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.1
+//     Runtime Version:4.0.30319.225
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
@@ -9,8 +9,10 @@
 //------------------------------------------------------------------------------
 
-namespace HeuristicLab.PluginInfrastructure.Advanced.DeploymentService {
-
-
-  [System.Diagnostics.DebuggerStepThroughAttribute()]
+namespace HeuristicLab.PluginInfrastructure.Advanced.DeploymentService
+{
+    using System.Runtime.Serialization;
+    
+    
+    [System.Diagnostics.DebuggerStepThroughAttribute()]
     [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
     [System.Runtime.Serialization.DataContractAttribute(Name="PluginDescription", Namespace="http://schemas.datacontract.org/2004/07/HeuristicLab.Services.Deployment", IsReference=true)]
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicDiscriminantFunctionClassificationSolutionSimplifierView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicDiscriminantFunctionClassificationSolutionSimplifierView.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification.Views/3.4/InteractiveSymbolicDiscriminantFunctionClassificationSolutionSimplifierView.cs	(revision 6415)
@@ -51,5 +51,4 @@
     protected override void UpdateModel(ISymbolicExpressionTree tree) {
       Content.Model = new SymbolicDiscriminantFunctionClassificationModel(tree, Content.Model.Interpreter);
-      Content.SetClassDistibutionCutPointThresholds();
     }
 
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicClassificationSolution.cs	(revision 6415)
@@ -20,15 +20,9 @@
 #endregion
 
-using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.Operators;
-using HeuristicLab.Parameters;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using System;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Classification {
@@ -69,5 +63,5 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic classification model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic classification model.", new IntValue()));
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -76,10 +70,10 @@
     }
 
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      RecalculateResults();
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
     }
 
-    private new void RecalculateResults() {
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Classification/3.4/SymbolicDiscriminantFunctionClassificationSolution.cs	(revision 6415)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -67,5 +66,5 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic classification model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic classification model.", new IntValue()));
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -74,10 +73,10 @@
     }
 
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      RecalculateResults();
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
     }
 
-    private new void RecalculateResults() {
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Regression/3.4/SymbolicRegressionSolution.cs	(revision 6415)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -63,5 +62,5 @@
       Add(new Result(ModelLengthResultName, "Length of the symbolic regression model.", new IntValue()));
       Add(new Result(ModelDepthResultName, "Depth of the symbolic regression model.", new IntValue()));
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -70,10 +69,10 @@
     }
 
-    protected override void OnModelChanged(EventArgs e) {
-      RecalculateResults();
-      base.OnModelChanged(e);
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
     }
 
-    protected new void RecalculateResults() {
+    private void CalculateResults() {
       ModelLength = Model.SymbolicExpressionTree.Length;
       ModelDepth = Model.SymbolicExpressionTree.Depth;
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/Symbols/VariableView.cs	(revision 6415)
@@ -80,5 +80,4 @@
     protected override void OnContentChanged() {
       base.OnContentChanged();
-      variableNamesView.Content.Clear();
       UpdateControl();
     }
@@ -105,7 +104,7 @@
     private void variableNames_Changed(object sender, CollectionItemsChangedEventArgs<StringValue> args) {
       if (Content != null) {
-        Content.Changed -= new EventHandler(Content_Changed);
+        DeregisterContentEvents();
         Content.VariableNames = variableNamesView.Content.CheckedItems.Select(x => x.Value).ToList();
-        Content.Changed += new EventHandler(Content_Changed);
+        RegisterContentEvents();
       }
     }
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 6415)
@@ -86,5 +86,5 @@
         StringMatrix matrix = null;
         if (Content != null) {
-          string[,] values = new string[Content.ProblemData.Dataset.Rows, 5];
+          string[,] values = new string[Content.ProblemData.Dataset.Rows, 4];
 
           double[] target = Content.ProblemData.Dataset.GetVariableValues(Content.ProblemData.TargetVariable);
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 6415)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -66,5 +65,5 @@
       Add(new Result(TrainingAccuracyResultName, "Accuracy of the model on the training partition (percentage of correctly classified instances).", new PercentValue()));
       Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue()));
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -73,15 +72,9 @@
     }
 
-    protected override void OnProblemDataChanged(EventArgs e) {
-      base.OnProblemDataChanged(e);
-      RecalculateResults();
+    protected override void RecalculateResults() {
+      CalculateResults();
     }
 
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      RecalculateResults();
-    }
-
-    protected void RecalculateResults() {
+    private void CalculateResults() {
       double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
       IEnumerable<double> originalTrainingClassValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 6415)
@@ -25,7 +25,7 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Data;
 using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 
 namespace HeuristicLab.Problems.DataAnalysis {
@@ -89,7 +89,10 @@
       Add(new Result(TrainingRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
       Add(new Result(TestRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
+      SetAccuracyMaximizingThresholds();
+
+      //mkommend: important to recalculate accuracy because during the calculation before no thresholds were present     
+      base.RecalculateResults();
+      CalculateResults();
       RegisterEventHandler();
-      SetAccuracyMaximizingThresholds();
-      RecalculateResults();
     }
 
@@ -99,5 +102,17 @@
     }
 
-    protected new void RecalculateResults() {
+    protected override void OnModelChanged(EventArgs e) {
+      DeregisterEventHandler();
+      SetAccuracyMaximizingThresholds();
+      RegisterEventHandler();
+      base.OnModelChanged(e);
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateResults();
+    }
+
+    private void CalculateResults() {
       double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
       IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
@@ -119,4 +134,7 @@
     private void RegisterEventHandler() {
       Model.ThresholdsChanged += new EventHandler(Model_ThresholdsChanged);
+    }
+    private void DeregisterEventHandler() {
+      Model.ThresholdsChanged -= new EventHandler(Model_ThresholdsChanged);
     }
     private void Model_ThresholdsChanged(object sender, EventArgs e) {
@@ -142,17 +160,5 @@
     }
 
-    protected override void OnModelChanged(EventArgs e) {
-      base.OnModelChanged(e);
-      SetAccuracyMaximizingThresholds();
-      RecalculateResults();
-    }
-
-    protected override void OnProblemDataChanged(EventArgs e) {
-      base.OnProblemDataChanged(e);
-      SetAccuracyMaximizingThresholds();
-      RecalculateResults();
-    }
     protected virtual void OnModelThresholdsChanged(EventArgs e) {
-      base.OnModelChanged(e);
       RecalculateResults();
     }
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 6415)
@@ -45,4 +45,7 @@
     }
 
+    protected override void RecalculateResults() {
+    }
+
     #region IClusteringSolution Members
 
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 6415)
@@ -86,4 +86,6 @@
     }
 
+    protected abstract void RecalculateResults();
+
     private void ProblemData_Changed(object sender, EventArgs e) {
       OnProblemDataChanged(e);
@@ -92,4 +94,5 @@
     public event EventHandler ModelChanged;
     protected virtual void OnModelChanged(EventArgs e) {
+      RecalculateResults();
       var listeners = ModelChanged;
       if (listeners != null) listeners(this, e);
@@ -98,4 +101,5 @@
     public event EventHandler ProblemDataChanged;
     protected virtual void OnProblemDataChanged(EventArgs e) {
+      RecalculateResults();
       var listeners = ProblemDataChanged;
       if (listeners != null) listeners(this, e);
Index: branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 6414)
+++ branches/GP.Grammar.Editor/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 6415)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -110,5 +109,5 @@
       Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
 
-      RecalculateResults();
+      CalculateResults();
     }
 
@@ -117,14 +116,9 @@
     }
 
-    protected override void OnProblemDataChanged(EventArgs e) {
-      RecalculateResults();
-      base.OnProblemDataChanged(e);
-    }
-    protected override void OnModelChanged(EventArgs e) {
-      RecalculateResults();
-      base.OnModelChanged(e);
+    protected override void RecalculateResults() {
+      CalculateResults();
     }
 
-    protected void RecalculateResults() {
+    private void CalculateResults() {
       double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
       IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetEnumeratedVariableValues(ProblemData.TargetVariable, ProblemData.TrainingIndizes);
