Index: branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 10564)
+++ branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 10798)
@@ -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 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 InteractiveSymbolicExpressionTreeChart treeChart;
     private System.Windows.Forms.SplitContainer splitContainer;
     private HeuristicLab.MainForm.WindowsForms.ViewHost viewHost;
Index: branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 10564)
+++ branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 10798)
@@ -1,5 +1,5 @@
 ﻿#region License Information
 /* HeuristicLab
- * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
  *
  * This file is part of HeuristicLab.
@@ -33,12 +33,82 @@
   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 }
+    private TreeState treeState;
 
     public 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));
+        changedNodes.Remove(oldChild);
+        foldedNodes.Remove(oldChild);
+        if (removeSubtree) {
+          foreach (var subtree in oldChild.IterateNodesPrefix()) {
+            changedNodes.Remove(subtree);
+            foldedNodes.Remove(subtree);
+          }
+        } else {
+          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;
+      if (treeState == TreeState.Valid) UpdateModel(Content.Model.SymbolicExpressionTree);
+    }
+
+    private bool IsValid(ISymbolicExpressionTree tree) {
+      treeChart.Tree = tree;
+      treeChart.Repaint();
+      bool valid = !tree.IterateNodesPostfix().Any(node => node.SubtreeCount < node.Symbol.MinimumArity || 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 +153,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,11 +174,18 @@
 
     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("VisualNode content cannot be null."); }
       var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.Content;
-      if (symbExprTreeNode == null) return;
       var tree = Content.Model.SymbolicExpressionTree;
       var parent = symbExprTreeNode.Parent;
       int indexOfSubtree = parent.IndexOfSubtree(symbExprTreeNode);
-      if (foldedNodes.ContainsKey(symbExprTreeNode)) {
+      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);
@@ -119,6 +196,6 @@
     private void SwitchNodeWithReplacementNode(ISymbolicExpressionTreeNode parent, int subTreeIndex) {
       ISymbolicExpressionTreeNode subTree = parent.GetSubtree(subTreeIndex);
-      parent.RemoveSubtree(subTreeIndex);
       if (foldedNodes.ContainsKey(subTree)) {
+        parent.RemoveSubtree(subTreeIndex);
         var replacementNode = foldedNodes[subTree];
         parent.InsertSubtree(subTreeIndex, replacementNode);
@@ -133,5 +210,5 @@
       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);
 
@@ -158,5 +235,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: branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicExpressionTreeChart.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 10564)
+++ branches/HeuristicLab.InteractiveTreeSimplifier/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 10798)
@@ -77,5 +77,5 @@
         pasteToolStripMenuItem.Enabled = tempNode != null && insertNodeToolStripMenuItem.Enabled
                                                           && !(lastOp == EditOp.CutSubtree
-                                                               && tempNode.IterateNodesBreadth().Contains(currSelected.Content));
+                                                          && tempNode.IterateNodesBreadth().Contains(currSelected.Content));
       }
     }
