Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 11085)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 11086)
@@ -55,5 +55,5 @@
       this.btnSimplify = new System.Windows.Forms.Button();
       this.treeStatusLabel = new System.Windows.Forms.Label();
-      this.treeChart = new HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart();
+      this.treeChart = new HeuristicLab.Problems.DataAnalysis.Symbolic.Views.InteractiveSymbolicExpressionTreeChart();
       this.grpViewHost = new System.Windows.Forms.GroupBox();
       ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
@@ -230,5 +230,5 @@
     #endregion
 
-    private HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views.SymbolicExpressionTreeChart treeChart;
+    private HeuristicLab.Problems.DataAnalysis.Symbolic.Views.InteractiveSymbolicExpressionTreeChart treeChart;
     private System.Windows.Forms.SplitContainer splitContainer;
     private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 11085)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 11086)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2014 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -33,12 +33,97 @@
   public abstract partial class InteractiveSymbolicDataAnalysisSolutionSimplifierView : AsynchronousContentView {
     private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> foldedNodes;
+    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> changedNodes;
     private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
+
     private enum TreeState { Valid, Invalid }
-
-    public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
+    private TreeState treeState;
+
+    protected InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
       InitializeComponent();
       foldedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
+      changedNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
       nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
       this.Caption = "Interactive Solution Simplifier";
+
+      // initialize the tree modifier that will be used to perform edit operations over the tree
+      treeChart.ModifyTree = Modify;
+    }
+
+    /// <summary>
+    /// Remove, Replace or Insert subtrees
+    /// </summary>
+    /// <param name="tree">The symbolic expression tree</param>
+    /// <param name="parent">The insertion point (ie, the parent node who will receive a new child)</param>
+    /// <param name="oldChild">The subtree to be replaced</param>
+    /// <param name="newChild">The replacement subtree</param>
+    /// <param name="removeSubtree">Flag used to indicate if whole subtrees should be removed (default behavior), or just the subtree root</param>
+    private void Modify(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent,
+      ISymbolicExpressionTreeNode oldChild, ISymbolicExpressionTreeNode newChild, bool removeSubtree = true) {
+      if (oldChild == null && newChild == null)
+        throw new ArgumentNullException("Cannot deduce operation type from the arguments. Please provide non null operands.");
+      if (oldChild == null) {
+        // insertion operation
+        parent.AddSubtree(newChild);
+        newChild.Parent = parent;
+      } else if (newChild == null) {
+        // removal operation
+        parent.RemoveSubtree(parent.IndexOfSubtree(oldChild));
+        if (!removeSubtree) {
+          for (int i = oldChild.SubtreeCount - 1; i >= 0; --i) {
+            var subtree = oldChild.GetSubtree(i);
+            oldChild.RemoveSubtree(i);
+            parent.AddSubtree(subtree);
+          }
+        }
+      } else {
+        // replacement operation
+        var replacementIndex = parent.IndexOfSubtree(oldChild);
+        parent.RemoveSubtree(replacementIndex);
+        parent.InsertSubtree(replacementIndex, newChild);
+        newChild.Parent = parent;
+        if (changedNodes.ContainsKey(oldChild)) {
+          changedNodes.Add(newChild, changedNodes[oldChild]); // so that on double click the original node is restored
+          changedNodes.Remove(oldChild);
+        } else {
+          changedNodes.Add(newChild, oldChild);
+        }
+      }
+      treeState = IsValid(tree) ? TreeState.Valid : TreeState.Invalid;
+      switch (treeState) {
+        case TreeState.Valid:
+          this.grpViewHost.Enabled = true;
+          UpdateModel(Content.Model.SymbolicExpressionTree);
+          break;
+        case TreeState.Invalid:
+          this.grpViewHost.Enabled = false;
+          break;
+      }
+    }
+
+    // the optimizer always assumes 2 children for multiplication and addition nodes
+    // thus, we enforce that the tree stays valid so that the constant optimization won't throw an exception
+    // by returning 2 as the minimum allowed arity for addition and multiplication symbols
+    private readonly Func<ISymbol, int> GetMinArity = symbol => {
+      var min = symbol.MinimumArity;
+      if (symbol is Multiplication || symbol is Division) return Math.Max(2, min);
+      return min;
+    };
+    private bool IsValid(ISymbolicExpressionTree tree) {
+      treeChart.Tree = tree;
+      treeChart.Repaint();
+      bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < GetMinArity(node.Symbol) || node.SubtreeCount > node.Symbol.MaximumArity);
+      if (valid) {
+        btnOptimizeConstants.Enabled = true;
+        btnSimplify.Enabled = true;
+        treeStatusValue.Text = "Valid";
+        treeStatusValue.ForeColor = Color.Green;
+      } else {
+        btnOptimizeConstants.Enabled = false;
+        btnSimplify.Enabled = false;
+        treeStatusValue.Text = "Invalid";
+        treeStatusValue.ForeColor = Color.Red;
+      }
+      this.Refresh();
+      return valid;
     }
 
@@ -83,9 +168,9 @@
 
       var impactAndReplacementValues = CalculateImpactAndReplacementValues(tree);
-      nodeImpacts = impactAndReplacementValues.ToDictionary(x => x.Key, x => x.Value.Item1);
       var replacementValues = impactAndReplacementValues.ToDictionary(x => x.Key, x => x.Value.Item2);
       foreach (var pair in replacementValues.Where(pair => !(pair.Key is ConstantTreeNode))) {
         foldedNodes[pair.Key] = MakeConstantTreeNode(pair.Value);
       }
+      nodeImpacts = impactAndReplacementValues.ToDictionary(x => x.Key, x => x.Value.Item1);
       PaintNodeImpacts();
     }
@@ -104,12 +189,22 @@
 
     private void treeChart_SymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
+      if (treeState == TreeState.Invalid) return;
       var visualNode = (VisualTreeNode<ISymbolicExpressionTreeNode>)sender;
-      if (visualNode.Content == null) { throw new Exception("Visual node content cannot be null."); }
+      if (visualNode.Content == null) { throw new Exception("VisualNode content cannot be null."); }
       var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.Content;
-      if (!foldedNodes.ContainsKey(symbExprTreeNode)) return; // constant nodes cannot be folded
+      var tree = Content.Model.SymbolicExpressionTree;
       var parent = symbExprTreeNode.Parent;
       int indexOfSubtree = parent.IndexOfSubtree(symbExprTreeNode);
-      SwitchNodeWithReplacementNode(parent, indexOfSubtree);
-      UpdateModel(Content.Model.SymbolicExpressionTree);
+      if (changedNodes.ContainsKey(symbExprTreeNode)) {
+        // undo node change
+        parent.RemoveSubtree(indexOfSubtree);
+        var originalNode = changedNodes[symbExprTreeNode];
+        parent.InsertSubtree(indexOfSubtree, originalNode);
+        changedNodes.Remove(symbExprTreeNode);
+      } else if (foldedNodes.ContainsKey(symbExprTreeNode)) {
+        // undo node folding
+        SwitchNodeWithReplacementNode(parent, indexOfSubtree);
+      }
+      UpdateModel(tree);
     }
 
@@ -130,9 +225,9 @@
       double max = impacts.Max();
       double min = impacts.Min();
-      foreach (var treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
+      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
         VisualTreeNode<ISymbolicExpressionTreeNode> visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
 
         if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
-          visualTree.ToolTip = visualTree.Content.ToString(); // to avoid duplicate tooltips
+          visualTree.ToolTip = visualTree.Content.ToString();
           double impact = nodeImpacts[treeNode];
 
@@ -156,5 +251,7 @@
         }
         if (visualTree != null)
-          if (treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) {
+          if (changedNodes.ContainsKey(treeNode)) {
+            visualTree.LineColor = Color.DodgerBlue;
+          } else if (treeNode is ConstantTreeNode && foldedNodes.ContainsKey(treeNode)) {
             visualTree.LineColor = Color.DarkOrange;
           }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.Designer.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.Designer.cs	(revision 11085)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.Designer.cs	(revision 11086)
@@ -56,4 +56,6 @@
       this.toolStripSeparator = new System.Windows.Forms.ToolStripSeparator();
       this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
+      this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
       this.SuspendLayout();
       // 
@@ -61,5 +63,5 @@
       // 
       this.insertNodeToolStripMenuItem.Name = "insertNodeToolStripMenuItem";
-      this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
+      this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
       this.insertNodeToolStripMenuItem.Text = "Insert Node";
       this.insertNodeToolStripMenuItem.Click += new System.EventHandler(this.insertNodeToolStripMenuItem_Click);
@@ -68,5 +70,5 @@
       // 
       this.changeNodeToolStripMenuItem.Name = "changeNodeToolStripMenuItem";
-      this.changeNodeToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
+      this.changeNodeToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
       this.changeNodeToolStripMenuItem.Text = "Change Node";
       this.changeNodeToolStripMenuItem.Click += new System.EventHandler(this.changeNodeToolStripMenuItem_Click);
@@ -75,6 +77,6 @@
       // 
       this.cutToolStripMenuItem.Name = "cutToolStripMenuItem";
-      this.cutToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
-      this.cutToolStripMenuItem.Text = "Cut";
+      this.cutToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
+      this.cutToolStripMenuItem.Text = "Cut Subtree";
       this.cutToolStripMenuItem.Click += new System.EventHandler(this.cutToolStripMenuItem_Click);
       // 
@@ -85,5 +87,5 @@
             this.removeSubtreeToolStripMenuItem});
       this.removeToolStripMenuItem.Name = "removeToolStripMenuItem";
-      this.removeToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
+      this.removeToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
       this.removeToolStripMenuItem.Text = "Remove";
       this.removeToolStripMenuItem.Click += new System.EventHandler(this.removeSubtreeToolStripMenuItem_Click);
@@ -106,6 +108,6 @@
       // 
       this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem";
-      this.pasteToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
-      this.pasteToolStripMenuItem.Text = "Paste";
+      this.pasteToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
+      this.pasteToolStripMenuItem.Text = "Paste Subtree";
       this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Clicked);
       // 
@@ -118,16 +120,28 @@
       // 
       this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
-      this.copyToolStripMenuItem.Size = new System.Drawing.Size(147, 22);
-      this.copyToolStripMenuItem.Text = "Copy";
+      this.copyToolStripMenuItem.Size = new System.Drawing.Size(165, 22);
+      this.copyToolStripMenuItem.Text = "Copy Subtree";
       this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
+      // 
+      // toolStripSeparator1
+      // 
+      this.toolStripSeparator1.Name = "toolStripSeparator1";
+      this.toolStripSeparator1.Size = new System.Drawing.Size(162, 6);
+      // 
+      // toolStripSeparator2
+      // 
+      this.toolStripSeparator2.Name = "toolStripSeparator2";
+      this.toolStripSeparator2.Size = new System.Drawing.Size(162, 6);
       //
       // contextMenuStrip
       //
       this.contextMenuStrip.Opened += this.contextMenuStrip_Opened;
-      this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { insertNodeToolStripMenuItem, 
+      this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { toolStripSeparator1,
+                                                                 insertNodeToolStripMenuItem, 
+                                                                 removeToolStripMenuItem, 
                                                                  changeNodeToolStripMenuItem, 
+                                                                 toolStripSeparator2,
                                                                  copyToolStripMenuItem, 
                                                                  cutToolStripMenuItem, 
-                                                                 removeToolStripMenuItem, 
                                                                  pasteToolStripMenuItem });
       // 
@@ -139,5 +153,4 @@
       this.Name = "InteractiveSymbolicExpressionTreeChart";
       this.ResumeLayout(false);
-
     }
 
@@ -154,4 +167,6 @@
     private ToolStripSeparator toolStripSeparator;
     private ToolStripMenuItem copyToolStripMenuItem;
+    private ToolStripSeparator toolStripSeparator1;
+    private ToolStripSeparator toolStripSeparator2;
   }
 }
Index: /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
===================================================================
--- /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 11085)
+++ /trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 11086)
@@ -83,17 +83,5 @@
     protected override void OnSymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
       currSelected = (VisualTreeNode<ISymbolicExpressionTreeNode>)sender; ;
-      if (currSelected != null) {
-        currSelected.LineColor = Color.FromArgb(130, currSelected.LineColor);
-        RepaintNode(currSelected);
-      }
       base.OnSymbolicExpressionTreeNodeClicked(sender, e);
-    }
-
-    protected override void SymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
-      if (currSelected != null) {
-        currSelected.LineColor = Color.FromArgb(255, currSelected.LineColor);
-        RepaintNode(currSelected);
-      }
-      base.SymbolicExpressionTreeChart_MouseClick(sender, e);
     }
 
@@ -108,5 +96,5 @@
 
       using (var dialog = new InsertNodeDialog()) {
-        dialog.SetAllowedSymbols(parent.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun)));
+        dialog.SetAllowedSymbols(parent.Grammar.Symbols.Where(s => !(s is ProgramRootSymbol || s is StartSymbol || s is Defun))); // allow everything
         dialog.ShowDialog(this);
         if (dialog.DialogResult != DialogResult.OK) return;
@@ -172,9 +160,9 @@
         foreach (var subtree in tempNode.IterateNodesPostfix()) {
           var visualNode = GetVisualSymbolicExpressionTreeNode(subtree);
-          visualNode.LineColor = Color.FromArgb(255, visualNode.LineColor); // reset the alpha value to 255
-          visualNode.TextColor = Color.FromArgb(255, visualNode.TextColor);
+          visualNode.LineColor = Color.Black;
+          visualNode.TextColor = Color.Black;
           if (subtree.Parent != null) {
             var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(subtree.Parent, subtree);
-            visualLine.LineColor = Color.FromArgb(255, visualLine.LineColor);
+            visualLine.LineColor = Color.Black;
           }
         }
@@ -183,13 +171,13 @@
       foreach (var node in tempNode.IterateNodesPostfix()) {
         var visualNode = GetVisualSymbolicExpressionTreeNode(node);
-        visualNode.LineColor = Color.FromArgb(100, visualNode.LineColor);
-        visualNode.TextColor = Color.FromArgb(100, visualNode.TextColor);
+        visualNode.LineColor = Color.LightGray;
+        visualNode.TextColor = Color.LightGray;
         foreach (var subtree in node.Subtrees) {
           var visualLine = GetVisualSymbolicExpressionTreeNodeConnection(node, subtree);
-          visualLine.LineColor = Color.FromArgb(100, visualLine.LineColor);
-        }
-      }
-      currSelected = null;
-      Repaint();
+          visualLine.LineColor = Color.LightGray;
+        }
+      }
+      currSelected = null;
+      RepaintNodes(); // no need to redo the layout and repaint everything since this operation does not change the tree
     }
     private void removeNodeToolStripMenuItem_Click(object sender, EventArgs e) {
