Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8950)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.Views-3.4.csproj	(revision 8980)
@@ -175,9 +175,15 @@
       <DependentUpon>VariableView.cs</DependentUpon>
     </Compile>
-    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeChangeValueDialog.cs">
+    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeConstantNodeEditDialog.cs">
       <SubType>Form</SubType>
     </Compile>
-    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeChangeValueDialog.Designer.cs">
-      <DependentUpon>SymbolicExpressionTreeNodeChangeValueDialog.cs</DependentUpon>
+    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs">
+      <DependentUpon>SymbolicExpressionTreeConstantNodeEditDialog.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeVariableNodeEditDialog.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="TreeEditDialogs\SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs">
+      <DependentUpon>SymbolicExpressionTreeVariableNodeEditDialog.cs</DependentUpon>
     </Compile>
     <Compile Include="TreeEditDialogs\SymbolicExpressionTreeNodeInsertDialog.cs">
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 8950)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.Designer.cs	(revision 8980)
@@ -159,5 +159,4 @@
       this.treeChart.Tree = null;
       this.treeChart.SymbolicExpressionTreeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeChanged);
-      this.treeChart.SymbolicExpressionTreeNodeChanged += new System.EventHandler(this.treeChart_SymbolicExpressionTreeNodeChanged);
       this.treeChart.SymbolicExpressionTreeNodeDoubleClicked += new System.Windows.Forms.MouseEventHandler(this.treeChart_SymbolicExpressionTreeNodeDoubleClicked);
       // 
@@ -190,5 +189,4 @@
       this.grpViewHost.ResumeLayout(false);
       this.ResumeLayout(false);
-
     }
 
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 8950)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicDataAnalysisSolutionSimplifierView.cs	(revision 8980)
@@ -34,6 +34,4 @@
     private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> replacementNodes;
     private Dictionary<ISymbolicExpressionTreeNode, double> nodeImpacts;
-    private Dictionary<ISymbolicExpressionTreeNode, double> originalValues;
-    private Dictionary<ISymbolicExpressionTreeNode, string> originalVariableNames;
 
     public InteractiveSymbolicDataAnalysisSolutionSimplifierView() {
@@ -41,7 +39,4 @@
       replacementNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
       nodeImpacts = new Dictionary<ISymbolicExpressionTreeNode, double>();
-      originalValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
-      originalVariableNames = new Dictionary<ISymbolicExpressionTreeNode, string>();
-
       this.Caption = "Interactive Solution Simplifier";
     }
@@ -105,43 +100,19 @@
       var symbExprTreeNode = (SymbolicExpressionTreeNode)visualNode.SymbolicExpressionTreeNode;
       if (symbExprTreeNode == null) return;
+      if (!replacementNodes.ContainsKey(symbExprTreeNode)) return;
       var tree = Content.Model.SymbolicExpressionTree;
+      var replacementNode = replacementNodes[symbExprTreeNode];
+      int indexOfReplacementNode = symbExprTreeNode.Parent.IndexOfSubtree(symbExprTreeNode);
+      SwitchNodeWithReplacementNode(symbExprTreeNode.Parent, indexOfReplacementNode);
+      // show only interesting part of solution 
+      treeChart.Tree = tree.Root.SubtreeCount > 1
+                         ? new SymbolicExpressionTree(tree.Root)
+                         : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
+      UpdateModel(tree);
+      var vNode = treeChart.GetVisualSymbolicExpressionTreeNode(replacementNode);
+      vNode.SymbolicExpressionTreeNode = replacementNode;
 
-      bool update = false;
-      // check if the node value/weight has been altered
-      // if so, the first double click will return the node to its original value/weight/variable name
-      // the next double click will replace the ConstantNode with the original SymbolicExpressionTreeNode
-      if (originalVariableNames.ContainsKey(symbExprTreeNode)) {
-        var variable = (VariableTreeNode)symbExprTreeNode;
-        variable.VariableName = originalVariableNames[symbExprTreeNode];
-        originalVariableNames.Remove(variable);
-        update = true;
-      } else if (originalValues.ContainsKey(symbExprTreeNode)) {
-        double value = originalValues[symbExprTreeNode];
-        if (symbExprTreeNode.Symbol is Constant) {
-          var constantTreeNode = (ConstantTreeNode)symbExprTreeNode;
-          constantTreeNode.Value = value;
-        } else if (symbExprTreeNode.Symbol is Variable) {
-          var variable = (VariableTreeNode)symbExprTreeNode;
-          variable.Weight = value;
-        }
-        originalValues.Remove(symbExprTreeNode);
-        update = true;
-      } else if (replacementNodes.ContainsKey(symbExprTreeNode)) {
-        foreach (var treeNode in tree.IterateNodesPostfix()) {
-          for (int i = 0; i < treeNode.SubtreeCount; i++) {
-            var subtree = treeNode.GetSubtree(i);
-            if (subtree == symbExprTreeNode) {
-              SwitchNodeWithReplacementNode(treeNode, i);
-              // show only interesting part of solution 
-              treeChart.Tree = tree.Root.SubtreeCount > 1
-                                 ? new SymbolicExpressionTree(tree.Root)
-                                 : new SymbolicExpressionTree(tree.Root.GetSubtree(0).GetSubtree(0));
-              update = true;
-            }
-          }
-          if (update) break;
-        }
-      }
-      if (update) UpdateModel(tree);
+      vNode.LineColor = replacementNode is ConstantTreeNode ? Color.DarkOrange : Color.Black;
+      treeChart.RepaintNode(vNode);
     }
 
@@ -149,37 +120,4 @@
       UpdateModel(Content.Model.SymbolicExpressionTree);
       UpdateView();
-    }
-
-    private void treeChart_SymbolicExpressionTreeNodeChanged(object sender, EventArgs e) {
-      var dialog = (ValueChangeDialog)sender;
-      bool flag1 = false, flag2 = false;
-      var node = dialog.Content;
-
-      if (node is VariableTreeNode) {
-        var variable = (VariableTreeNode)node;
-        var weight = double.Parse(dialog.newValueTextBox.Text);
-        var name = (string)dialog.variableNamesCombo.SelectedItem;
-        if (!variable.Weight.Equals(weight)) {
-          flag1 = true;
-          originalValues[variable] = variable.Weight;
-          variable.Weight = weight;
-        }
-        if (!variable.VariableName.Equals(name)) {
-          flag2 = true;
-          originalVariableNames[variable] = variable.VariableName;
-          variable.VariableName = name;
-        }
-      } else if (node is ConstantTreeNode) {
-        var constant = (ConstantTreeNode)node;
-        var value = double.Parse(dialog.newValueTextBox.Text);
-        if (!constant.Value.Equals(value)) {
-          flag1 = true;
-          originalValues[constant] = constant.Value;
-          constant.Value = value;
-        }
-      }
-      if (flag1 || flag2) {
-        UpdateView();
-      }
     }
 
@@ -202,12 +140,4 @@
       foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
         VisualSymbolicExpressionTreeNode visualTree = treeChart.GetVisualSymbolicExpressionTreeNode(treeNode);
-        bool flag1 = replacementNodes.ContainsKey(treeNode);
-        bool flag2 = originalValues.ContainsKey(treeNode);
-        bool flag3 = treeNode is ConstantTreeNode;
-
-        if (flag2) // constant or variable node was changed
-          visualTree.ToolTip += Environment.NewLine + "Original value: " + originalValues[treeNode];
-        else if (flag1 && flag3) // symbol node was folded to a constant
-          visualTree.ToolTip += Environment.NewLine + "Original node: " + replacementNodes[treeNode];
 
         if (!(treeNode is ConstantTreeNode) && nodeImpacts.ContainsKey(treeNode)) {
@@ -232,19 +162,11 @@
           }
         }
-      }
-      this.PaintCollapsedNodes();
-      this.treeChart.Repaint();
-    }
-
-    private void PaintCollapsedNodes() {
-      foreach (ISymbolicExpressionTreeNode treeNode in Content.Model.SymbolicExpressionTree.IterateNodesPostfix()) {
-        bool flag1 = replacementNodes.ContainsKey(treeNode);
-        bool flag2 = originalValues.ContainsKey(treeNode);
-        if (flag1 && treeNode is ConstantTreeNode) {
-          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = flag2 ? Color.DarkViolet : Color.DarkOrange;
-        } else if (flag2) {
-          this.treeChart.GetVisualSymbolicExpressionTreeNode(treeNode).LineColor = Color.DodgerBlue;
+        if (visualTree != null && treeNode is ConstantTreeNode && replacementNodes.ContainsKey(treeNode)) {
+          visualTree.LineColor = Color.DarkOrange;
         }
       }
+      // repaint nodes and refresh
+      treeChart.RepaintNodes();
+      treeChart.Refresh();
     }
 
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 8950)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.Designer.cs	(revision 8980)
@@ -47,7 +47,6 @@
     /// </summary>
     private void InitializeComponent() {
-      this.DoubleBuffered = true;
       this.insertNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
-      this.changeValueToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+      this.editNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
       this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
       this.copyNodeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -67,14 +66,14 @@
       // 
       this.insertNodeToolStripMenuItem.Name = "insertNodeToolStripMenuItem";
-      this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+      this.insertNodeToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
       this.insertNodeToolStripMenuItem.Text = "Insert Node";
       this.insertNodeToolStripMenuItem.Click += new System.EventHandler(this.insertNodeToolStripMenuItem_Click);
       // 
-      // changeValueToolStripMenuItem
-      // 
-      this.changeValueToolStripMenuItem.Name = "changeValueToolStripMenuItem";
-      this.changeValueToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
-      this.changeValueToolStripMenuItem.Text = "Change Value";
-      this.changeValueToolStripMenuItem.Click += new System.EventHandler(this.changeValueToolStripMenuItem_Click);
+      // editNodeToolStripMenuItem
+      // 
+      this.editNodeToolStripMenuItem.Name = "editNodeToolStripMenuItem";
+      this.editNodeToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
+      this.editNodeToolStripMenuItem.Text = "Edit";
+      this.editNodeToolStripMenuItem.Click += new System.EventHandler(this.editNodeToolStripMenuItem_Click);
       // 
       // copyToolStripMenuItem
@@ -84,5 +83,5 @@
             this.copySubtreeToolStripMenuItem});
       this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
-      this.copyToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+      this.copyToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
       this.copyToolStripMenuItem.Text = "Copy";
       // 
@@ -107,5 +106,5 @@
             this.cutSubtreeToolStripMenuItem});
       this.cutToolStripMenuItem.Name = "cutToolStripMenuItem";
-      this.cutToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+      this.cutToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
       this.cutToolStripMenuItem.Text = "Cut";
       // 
@@ -130,5 +129,5 @@
             this.deleteSubtreeToolStripMenuItem});
       this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
-      this.deleteToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+      this.deleteToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
       this.deleteToolStripMenuItem.Text = "Delete";
       // 
@@ -150,17 +149,17 @@
       // 
       this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem";
-      this.pasteToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+      this.pasteToolStripMenuItem.Size = new System.Drawing.Size(135, 22);
       this.pasteToolStripMenuItem.Text = "Paste";
       this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Clicked);
-      //
-      // contextMenuStrip
-      //
+      // 
+      // contextMenuStrip 
+      // 
       this.contextMenuStrip.Opened += this.contextMenuStrip_Opened;
-      this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { insertNodeToolStripMenuItem,
-                                                                 changeValueToolStripMenuItem, 
-                                                                 copyToolStripMenuItem, 
-                                                                 cutToolStripMenuItem, 
-                                                                 deleteToolStripMenuItem, 
-                                                                 pasteToolStripMenuItem });
+      this.contextMenuStrip.Items.AddRange(new ToolStripItem[] { insertNodeToolStripMenuItem, 
+ 		                                                             editNodeToolStripMenuItem,  
+ 		                                                             copyToolStripMenuItem,  
+ 		                                                             cutToolStripMenuItem,  
+ 		                                                             deleteToolStripMenuItem,  
+ 		                                                             pasteToolStripMenuItem });
       // 
       // treeStatusLabel
@@ -191,5 +190,7 @@
       this.Controls.Add(this.treeStatusLabel);
       this.Controls.Add(this.treeStatusValue);
+      this.DoubleBuffered = true;
       this.Name = "InteractiveSymbolicExpressionTreeChart";
+      this.MouseClick += new System.Windows.Forms.MouseEventHandler(this.InteractiveSymbolicExpressionTreeChart_MouseClick);
       this.ResumeLayout(false);
       this.PerformLayout();
@@ -198,5 +199,5 @@
 
     private ToolStripMenuItem insertNodeToolStripMenuItem;
-    private ToolStripMenuItem changeValueToolStripMenuItem;
+    private ToolStripMenuItem editNodeToolStripMenuItem;
     private ToolStripMenuItem copyToolStripMenuItem;
     private ToolStripMenuItem copyNodeToolStripMenuItem;
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 8950)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/InteractiveSymbolicExpressionTreeChart.cs	(revision 8980)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Drawing;
 using System.Linq;
@@ -29,6 +30,5 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
   public sealed partial class InteractiveSymbolicExpressionTreeChart : SymbolicExpressionTreeChart {
-    private ISymbolicExpressionTreeNode tempNode;
-    private VisualSymbolicExpressionTreeNode lastSelected; // previously selected node
+    private ISymbolicExpressionTreeNode tempNode; // node in clipboard (to be cut/copy/pasted etc)
     private VisualSymbolicExpressionTreeNode currSelected; // currently selected node
     private enum EditOp { NoOp, CopyNode, CopySubtree, CutNode, CutSubtree, DeleteNode, DeleteSubtree }
@@ -37,12 +37,12 @@
     private TreeState treeState = TreeState.Valid; // tree edit operations must leave the tree in a valid state
 
+    private Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode> originalNodes; // map a new node to the original node it replaced
+
     public InteractiveSymbolicExpressionTreeChart() {
       InitializeComponent();
-      // add extra actions in the context menu strips
-
-
-      lastSelected = null;
       currSelected = null;
       tempNode = null;
+
+      originalNodes = new Dictionary<ISymbolicExpressionTreeNode, ISymbolicExpressionTreeNode>();
     }
 
@@ -65,12 +65,21 @@
         Repaint();
       }
+      foreach (var node in originalNodes.Keys) {
+        var visualNode = GetVisualSymbolicExpressionTreeNode(node);
+        if (visualNode == null) continue;
+        visualNode.LineColor = Color.DodgerBlue;
+        RepaintNode(visualNode);
+      }
     }
 
     private void contextMenuStrip_Opened(object sender, EventArgs e) {
-      var menu = sender as ContextMenuStrip;
-      if (menu == null) return;
+      var menuStrip = (ContextMenuStrip)sender;
+      var point = menuStrip.SourceControl.PointToClient(Cursor.Position);
+      var ea = new MouseEventArgs(MouseButtons.Left, 1, point.X, point.Y, 0);
+      InteractiveSymbolicExpressionTreeChart_MouseClick(null, ea);
+
       if (currSelected == null) {
         insertNodeToolStripMenuItem.Visible = false;
-        changeValueToolStripMenuItem.Visible = false;
+        editNodeToolStripMenuItem.Visible = false;
         copyToolStripMenuItem.Visible = false;
         cutToolStripMenuItem.Visible = false;
@@ -79,6 +88,6 @@
       } else {
         var node = currSelected.SymbolicExpressionTreeNode;
-        changeValueToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode);
-        insertNodeToolStripMenuItem.Visible = !changeValueToolStripMenuItem.Visible;
+        editNodeToolStripMenuItem.Visible = (node is SymbolicExpressionTreeTerminalNode);
+        insertNodeToolStripMenuItem.Visible = !editNodeToolStripMenuItem.Visible;
         copyToolStripMenuItem.Visible = true;
         cutToolStripMenuItem.Visible = true;
@@ -89,73 +98,115 @@
 
     protected override void OnSymbolicExpressionTreeNodeClicked(object sender, MouseEventArgs e) {
-      var visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
-      if (visualTreeNode == null || visualTreeNode == currSelected) return;
-      lastSelected = currSelected;
-      if (lastSelected != null)
-        lastSelected.LineColor = Color.Black;
+      var visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
+      var lastSelected = currSelected;
+      if (lastSelected != null) {
+        lastSelected.LineColor = originalNodes.ContainsKey(lastSelected.SymbolicExpressionTreeNode) ? Color.DodgerBlue : Color.Black;
+        RepaintNode(lastSelected);
+      }
+
       currSelected = visualTreeNode;
-      currSelected.LineColor = Color.LightGreen;
-      Repaint();
-      base.OnSymbolicExpressionTreeNodeClicked(sender, e);
+      if (currSelected != null) {
+        currSelected.LineColor = Color.LightGreen;
+        RepaintNode(currSelected);
+      }
+    }
+
+    protected override void OnSymbolicExpressionTreeNodeDoubleClicked(object sender, MouseEventArgs e) {
+      var visualTreeNode = (VisualSymbolicExpressionTreeNode)sender;
+      if (originalNodes.ContainsKey(visualTreeNode.SymbolicExpressionTreeNode)) {
+        var originalNode = originalNodes[visualTreeNode.SymbolicExpressionTreeNode];
+
+        var parent = visualTreeNode.SymbolicExpressionTreeNode.Parent;
+        var i = parent.IndexOfSubtree(visualTreeNode.SymbolicExpressionTreeNode);
+        parent.RemoveSubtree(i);
+        parent.InsertSubtree(i, originalNode);
+
+        originalNodes.Remove(visualTreeNode.SymbolicExpressionTreeNode);
+        visualTreeNode.SymbolicExpressionTreeNode = originalNode;
+        OnSymbolicExpressionTreeChanged(sender, EventArgs.Empty);
+      } else {
+        currSelected = null; // because the tree node will be folded/unfolded 
+        base.OnSymbolicExpressionTreeNodeDoubleClicked(sender, e);
+        // at this point the tree got redrawn, so we mark the edited nodes
+        foreach (var node in originalNodes.Keys) {
+          var visualNode = GetVisualSymbolicExpressionTreeNode(node);
+          if (visualNode == null) continue;
+          visualNode.LineColor = Color.DodgerBlue;
+          RepaintNode(visualNode);
+        }
+      }
     }
 
     private void insertNodeToolStripMenuItem_Click(object sender, EventArgs e) {
       if (currSelected == null || currSelected.SymbolicExpressionTreeNode is SymbolicExpressionTreeTerminalNode) return;
-      var node = currSelected.SymbolicExpressionTreeNode;
+      var parent = currSelected.SymbolicExpressionTreeNode;
 
       using (var dialog = new InsertNodeDialog()) {
-        dialog.SetAllowedSymbols(node.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun)));
-        dialog.DialogValidated += InsertNodeDialog_Validated;
+        dialog.SetAllowedSymbols(parent.Grammar.AllowedSymbols.Where(s => s.Enabled && s.InitialFrequency > 0.0 && !(s is ProgramRootSymbol || s is StartSymbol || s is Defun)));
         dialog.ShowDialog(this);
-      }
-    }
-
-    private void changeValueToolStripMenuItem_Click(object sender, EventArgs e) {
+
+        if (dialog.DialogResult == DialogResult.OK) {
+          var symbol = dialog.SelectedSymbol();
+          var node = symbol.CreateTreeNode();
+          if (node is ConstantTreeNode) {
+            var constant = node as ConstantTreeNode;
+            constant.Value = double.Parse(dialog.constantValueTextBox.Text);
+          } else if (node is VariableTreeNode) {
+            var variable = node as VariableTreeNode;
+            variable.Weight = double.Parse(dialog.variableWeightTextBox.Text);
+            variable.VariableName = dialog.variableNamesCombo.Text;
+          } else {
+            if (node.Symbol.MinimumArity <= parent.SubtreeCount && node.Symbol.MaximumArity >= parent.SubtreeCount) {
+              for (int i = parent.SubtreeCount - 1; i >= 0; --i) {
+                var child = parent.GetSubtree(i);
+                parent.RemoveSubtree(i);
+                node.AddSubtree(child);
+              }
+            }
+          }
+          if (parent.Symbol.MaximumArity > parent.SubtreeCount) {
+            parent.AddSubtree(node);
+            Tree = Tree;
+          }
+          OnSymbolicExpressionTreeChanged(sender, e);
+        }
+      }
+    }
+
+    private void editNodeToolStripMenuItem_Click(object sender, EventArgs e) {
       if (currSelected == null) return;
-      var node = currSelected.SymbolicExpressionTreeNode;
-      using (var dialog = new ValueChangeDialog()) {
-        dialog.SetContent(node);
-        dialog.DialogValidated += ChangeValueDialog_Validated;
-        dialog.ShowDialog(this);
-      }
-    }
-
-    public event EventHandler SymbolicExpressionTreeNodeChanged;
-    private void OnSymbolicExpressionTreeNodeChanged(object sender, EventArgs e) {
-      var changed = SymbolicExpressionTreeNodeChanged;
-      if (changed != null)
-        SymbolicExpressionTreeNodeChanged(sender, e);
-    }
-
-    private void ChangeValueDialog_Validated(object sender, EventArgs e) {
-      OnSymbolicExpressionTreeNodeChanged(sender, e);
-    }
-
-    private void InsertNodeDialog_Validated(object sender, EventArgs e) {
-      var dialog = (InsertNodeDialog)sender;
-      var symbol = dialog.SelectedSymbol();
-      var node = symbol.CreateTreeNode();
-      var parent = currSelected.SymbolicExpressionTreeNode;
+
+      ISymbolicExpressionTreeNode node;
+      if (originalNodes.ContainsKey(currSelected.SymbolicExpressionTreeNode)) {
+        node = currSelected.SymbolicExpressionTreeNode;
+      } else {
+        node = (ISymbolicExpressionTreeNode)currSelected.SymbolicExpressionTreeNode.Clone();
+      }
+      var originalNode = currSelected.SymbolicExpressionTreeNode;
+      ISymbolicExpressionTreeNode newNode = null;
+      var result = DialogResult.Cancel;
       if (node is ConstantTreeNode) {
-        var constant = node as ConstantTreeNode;
-        constant.Value = double.Parse(dialog.constantValueTextBox.Text);
+        using (var dialog = new ConstantNodeEditDialog(node)) {
+          dialog.ShowDialog(this);
+          newNode = dialog.NewNode;
+          result = dialog.DialogResult;
+        }
       } else if (node is VariableTreeNode) {
-        var variable = node as VariableTreeNode;
-        variable.Weight = double.Parse(dialog.variableWeightTextBox.Text);
-        variable.VariableName = dialog.variableNamesCombo.Text;
-      } else {
-        if (node.Symbol.MinimumArity <= parent.SubtreeCount && node.Symbol.MaximumArity >= parent.SubtreeCount) {
-          for (int i = parent.SubtreeCount - 1; i >= 0; --i) {
-            var child = parent.GetSubtree(i);
-            parent.RemoveSubtree(i);
-            node.AddSubtree(child);
-          }
-        }
-      }
-      if (parent.Symbol.MaximumArity > parent.SubtreeCount) {
-        parent.AddSubtree(node);
-        Tree = Tree;
-      }
-      OnSymbolicExpressionTreeChanged(sender, e);
+        using (var dialog = new VariableNodeEditDialog(node)) {
+          dialog.ShowDialog(this);
+          newNode = dialog.NewNode;
+          result = dialog.DialogResult;
+        }
+      }
+      if (result != DialogResult.OK) return;
+      if (originalNode != newNode) {
+        var parent = originalNode.Parent;
+        int i = parent.IndexOfSubtree(originalNode);
+        parent.RemoveSubtree(i);
+        parent.InsertSubtree(i, newNode);
+        originalNodes[newNode] = originalNode;
+        currSelected.SymbolicExpressionTreeNode = newNode;
+      }
+      OnSymbolicExpressionTreeChanged(sender, EventArgs.Empty);
     }
 
@@ -171,5 +222,5 @@
     private void cutSubtreeToolStripMenuItem_Click(object sender, EventArgs e) {
       lastOp = EditOp.CutSubtree;
-      tempNode = currSelected.SymbolicExpressionTreeNode; // should never be null
+      tempNode = currSelected.SymbolicExpressionTreeNode;
       foreach (var node in tempNode.IterateNodesPostfix()) {
         var visualNode = GetVisualSymbolicExpressionTreeNode(node);
@@ -244,5 +295,5 @@
       // check if the copied/cut node (stored in the tempNode) can be inserted as a child of the current selected node
       var node = currSelected.SymbolicExpressionTreeNode;
-      if (node is ConstantTreeNode || node is VariableTreeNode) return; // nothing to do
+      if (node is ConstantTreeNode || node is VariableTreeNode) return;
       // check if the currently selected node can accept the copied node as a child 
       // no need to check the grammar, an arity check will do just fine here
@@ -254,6 +305,5 @@
               // arity checks to see if parent can accept node's children (we assume the grammar is already ok with that)
               // (otherise, the 'cut' part of the operation will just not do anything)
-              if (parent.Symbol.MaximumArity >= tempNode.SubtreeCount + parent.SubtreeCount - 1) {
-                // -1 because tempNode will be removed
+              if (parent.Symbol.MaximumArity >= tempNode.SubtreeCount + parent.SubtreeCount - 1) { // -1 because tempNode will be removed
                 parent.RemoveSubtree(parent.IndexOfSubtree(tempNode));
                 for (int i = tempNode.SubtreeCount - 1; i >= 0; --i) {
@@ -263,5 +313,4 @@
                 }
                 lastOp = EditOp.CopyNode;
-                currSelected = null;
               }
               break;
@@ -272,10 +321,9 @@
               parent.RemoveSubtree(parent.IndexOfSubtree(tempNode));
               lastOp = EditOp.CopySubtree; // do this so the next paste will actually perform a copy   
-              currSelected = null;
               break;
             }
           case (EditOp.CopyNode): {
               // copy node
-              var clone = (SymbolicExpressionTreeNode)tempNode.Clone(); // should never be null
+              var clone = (SymbolicExpressionTreeNode)tempNode.Clone();
               clone.Parent = tempNode.Parent;
               tempNode = clone;
@@ -292,6 +340,7 @@
         }
         node.AddSubtree(tempNode);
-        Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the graph
+        Tree = Tree; // hack in order to trigger the reinitialization of the dictionaries after new nodes appeared in the tree
         OnSymbolicExpressionTreeChanged(sender, e);
+        currSelected = null; // because the tree changed and was completely redrawn
       }
     }
@@ -305,4 +354,16 @@
       return true;
     }
+
+    private void InteractiveSymbolicExpressionTreeChart_MouseClick(object sender, MouseEventArgs e) {
+      var visualTreeNode = FindVisualSymbolicExpressionTreeNodeAt(e.X, e.Y);
+      if (currSelected != null) {
+        currSelected.LineColor = originalNodes.ContainsKey(currSelected.SymbolicExpressionTreeNode) ? Color.DodgerBlue : Color.Black;
+      }
+      currSelected = visualTreeNode;
+      if (currSelected != null) {
+        currSelected.LineColor = Color.LightGreen;
+        RepaintNode(currSelected);
+      }
+    }
   }
 }
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs	(revision 8980)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.Designer.cs	(revision 8980)
@@ -0,0 +1,162 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Problems.DataAnalysis.Symbolic.Views {
+  partial class ConstantNodeEditDialog {
+    /// <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) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form 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.components = new System.ComponentModel.Container();
+      this.originalValueLabel = new System.Windows.Forms.Label();
+      this.oldValueTextBox = new System.Windows.Forms.TextBox();
+      this.newValueTextBox = new System.Windows.Forms.TextBox();
+      this.newValueLabel = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // originalValueLabel
+      // 
+      this.originalValueLabel.AutoSize = true;
+      this.originalValueLabel.Location = new System.Drawing.Point(12, 9);
+      this.originalValueLabel.Name = "originalValueLabel";
+      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
+      this.originalValueLabel.TabIndex = 2;
+      this.originalValueLabel.Text = "Original Value";
+      // 
+      // oldValueTextBox
+      // 
+      this.oldValueTextBox.Location = new System.Drawing.Point(123, 6);
+      this.oldValueTextBox.Name = "oldValueTextBox";
+      this.oldValueTextBox.ReadOnly = true;
+      this.oldValueTextBox.Size = new System.Drawing.Size(131, 20);
+      this.oldValueTextBox.TabIndex = 3;
+      // 
+      // newValueTextBox
+      // 
+      this.newValueTextBox.Location = new System.Drawing.Point(123, 42);
+      this.newValueTextBox.Name = "newValueTextBox";
+      this.newValueTextBox.Size = new System.Drawing.Size(131, 20);
+      this.newValueTextBox.TabIndex = 0;
+      this.newValueTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
+      this.newValueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.newValueTextBox_Validating);
+      this.newValueTextBox.Validated += new System.EventHandler(this.newValueTextBox_Validated);
+      // 
+      // newValueLabel
+      // 
+      this.newValueLabel.AutoSize = true;
+      this.newValueLabel.Location = new System.Drawing.Point(12, 45);
+      this.newValueLabel.Name = "newValueLabel";
+      this.newValueLabel.Size = new System.Drawing.Size(59, 13);
+      this.newValueLabel.TabIndex = 5;
+      this.newValueLabel.Text = "New Value";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      this.errorProvider.RightToLeft = true;
+      // 
+      // okButton
+      // 
+      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+      this.okButton.Location = new System.Drawing.Point(15, 79);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 8;
+      this.okButton.Text = "OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.CausesValidation = false;
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(179, 79);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 9;
+      this.cancelButton.Text = "Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // ConstantNodeEditDialog
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.AutoSize = true;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(269, 116);
+      this.ControlBox = false;
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.Controls.Add(this.newValueLabel);
+      this.Controls.Add(this.newValueTextBox);
+      this.Controls.Add(this.oldValueTextBox);
+      this.Controls.Add(this.originalValueLabel);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "ConstantNodeEditDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Edit constant value";
+      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ConstantNodeEditDialog_KeyDown);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label originalValueLabel;
+    private System.Windows.Forms.TextBox oldValueTextBox;
+    private System.Windows.Forms.Label newValueLabel;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.Button okButton;
+    public System.Windows.Forms.TextBox newValueTextBox;
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.cs	(revision 8980)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeConstantNodeEditDialog.cs	(revision 8980)
@@ -0,0 +1,125 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ComponentModel;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
+  public partial class ConstantNodeEditDialog : Form {
+    private ConstantTreeNode constantTreeNode;
+    public ConstantTreeNode NewNode {
+      get { return constantTreeNode; }
+      set {
+        if (InvokeRequired)
+          Invoke(new Action<SymbolicExpressionTreeNode>(x => constantTreeNode = (ConstantTreeNode)x), value);
+        else
+          constantTreeNode = value;
+      }
+    }
+
+    public ConstantNodeEditDialog(ISymbolicExpressionTreeNode node) {
+      InitializeComponent();
+      oldValueTextBox.TabStop = false; // cannot receive focus using tab key
+      NewNode = (ConstantTreeNode)node;
+      InitializeFields();
+    }
+
+    private void InitializeFields() {
+      if (NewNode == null)
+        throw new ArgumentException("Node is not a constant.");
+      else {
+        this.Text = "Edit constant";
+        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(constantTreeNode.Value, 4).ToString();
+      }
+    }
+
+    #region text box validation and events
+    private void newValueTextBox_Validating(object sender, CancelEventArgs e) {
+      string errorMessage;
+      if (!ValidateNewValue(newValueTextBox.Text, out errorMessage)) {
+        e.Cancel = true;
+        errorProvider.SetError(newValueTextBox, errorMessage);
+        newValueTextBox.SelectAll();
+      }
+    }
+
+    private void newValueTextBox_Validated(object sender, EventArgs e) {
+      errorProvider.SetError(newValueTextBox, string.Empty);
+    }
+
+    private static bool ValidateNewValue(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        var sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    #endregion
+
+    // proxy handler passing key strokes to the parent control
+    private void childControl_KeyDown(object sender, KeyEventArgs e) {
+      ConstantNodeEditDialog_KeyDown(sender, e);
+    }
+
+    private void ConstantNodeEditDialog_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) {
+        if (!ValidateChildren()) return;
+        OnDialogValidated(this, e); // emit validated effect
+        Close();
+      }
+    }
+
+    public event EventHandler DialogValidated;
+    private void OnDialogValidated(object sender, EventArgs e) {
+      if (constantTreeNode == null) return;
+      var value = double.Parse(newValueTextBox.Text);
+      // we impose an extra validation condition: that the new value is different from the original value
+      if (constantTreeNode.Value.Equals(value)) return;
+
+      constantTreeNode.Value = value;
+      DialogResult = DialogResult.OK;
+      var dialogValidated = DialogValidated;
+      if (dialogValidated != null)
+        dialogValidated(sender, e);
+    }
+
+    private void cancelButton_Click(object sender, EventArgs e) {
+      Close();
+    }
+
+    private void okButton_Click(object sender, EventArgs e) {
+      if (ValidateChildren()) {
+        OnDialogValidated(this, e);
+        Close();
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeChangeValueDialog.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeChangeValueDialog.Designer.cs	(revision 8950)
+++ 	(revision )
@@ -1,190 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.Problems.DataAnalysis.Symbolic.Views {
-  partial class ValueChangeDialog {
-    /// <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) {
-        if (components != null) components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Windows Form 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.components = new System.ComponentModel.Container();
-      this.originalValueLabel = new System.Windows.Forms.Label();
-      this.oldValueTextBox = new System.Windows.Forms.TextBox();
-      this.newValueTextBox = new System.Windows.Forms.TextBox();
-      this.newValueLabel = new System.Windows.Forms.Label();
-      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
-      this.variableNameLabel = new System.Windows.Forms.Label();
-      this.variableNamesCombo = new System.Windows.Forms.ComboBox();
-      this.okButton = new System.Windows.Forms.Button();
-      this.cancelButton = new System.Windows.Forms.Button();
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
-      this.SuspendLayout();
-      // 
-      // originalValueLabel
-      // 
-      this.originalValueLabel.AutoSize = true;
-      this.originalValueLabel.Location = new System.Drawing.Point(12, 45);
-      this.originalValueLabel.Name = "originalValueLabel";
-      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
-      this.originalValueLabel.TabIndex = 2;
-      this.originalValueLabel.Text = "Original Value";
-      // 
-      // oldValueTextBox
-      // 
-      this.oldValueTextBox.Location = new System.Drawing.Point(123, 42);
-      this.oldValueTextBox.Name = "oldValueTextBox";
-      this.oldValueTextBox.ReadOnly = true;
-      this.oldValueTextBox.Size = new System.Drawing.Size(131, 20);
-      this.oldValueTextBox.TabIndex = 3;
-      // 
-      // newValueTextBox
-      // 
-      this.newValueTextBox.Location = new System.Drawing.Point(123, 82);
-      this.newValueTextBox.Name = "newValueTextBox";
-      this.newValueTextBox.Size = new System.Drawing.Size(131, 20);
-      this.newValueTextBox.TabIndex = 0;
-      this.newValueTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
-      this.newValueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.newValueTextBox_Validating);
-      this.newValueTextBox.Validated += new System.EventHandler(this.newValueTextBox_Validated);
-      // 
-      // newValueLabel
-      // 
-      this.newValueLabel.AutoSize = true;
-      this.newValueLabel.Location = new System.Drawing.Point(12, 85);
-      this.newValueLabel.Name = "newValueLabel";
-      this.newValueLabel.Size = new System.Drawing.Size(59, 13);
-      this.newValueLabel.TabIndex = 5;
-      this.newValueLabel.Text = "New Value";
-      // 
-      // errorProvider
-      // 
-      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
-      this.errorProvider.ContainerControl = this;
-      this.errorProvider.RightToLeft = true;
-      // 
-      // variableNameLabel
-      // 
-      this.variableNameLabel.AutoSize = true;
-      this.variableNameLabel.Location = new System.Drawing.Point(12, 7);
-      this.variableNameLabel.Name = "variableNameLabel";
-      this.variableNameLabel.Size = new System.Drawing.Size(76, 13);
-      this.variableNameLabel.TabIndex = 6;
-      this.variableNameLabel.Text = "Variable Name";
-      this.variableNameLabel.Visible = false;
-      // 
-      // variableNamesCombo
-      // 
-      this.variableNamesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-      this.variableNamesCombo.FormattingEnabled = true;
-      this.variableNamesCombo.Location = new System.Drawing.Point(123, 4);
-      this.variableNamesCombo.Name = "variableNamesCombo";
-      this.variableNamesCombo.Size = new System.Drawing.Size(131, 21);
-      this.variableNamesCombo.TabIndex = 7;
-      this.variableNamesCombo.Visible = false;
-      this.variableNamesCombo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
-      this.variableNamesCombo.Validating += new System.ComponentModel.CancelEventHandler(this.variableNamesCombo_Validating);
-      this.variableNamesCombo.Validated += new System.EventHandler(this.variableNamesCombo_Validated);
-      // 
-      // okButton
-      // 
-      this.okButton.Location = new System.Drawing.Point(15, 119);
-      this.okButton.Name = "okButton";
-      this.okButton.Size = new System.Drawing.Size(75, 23);
-      this.okButton.TabIndex = 8;
-      this.okButton.Text = "OK";
-      this.okButton.UseVisualStyleBackColor = true;
-      this.okButton.Click += new System.EventHandler(this.okButton_Click);
-      // 
-      // cancelButton
-      // 
-      this.cancelButton.CausesValidation = false;
-      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
-      this.cancelButton.Location = new System.Drawing.Point(179, 119);
-      this.cancelButton.Name = "cancelButton";
-      this.cancelButton.Size = new System.Drawing.Size(75, 23);
-      this.cancelButton.TabIndex = 9;
-      this.cancelButton.Text = "Cancel";
-      this.cancelButton.UseVisualStyleBackColor = true;
-      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
-      // 
-      // ValueChangeDialog
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.AutoSize = true;
-      this.CancelButton = this.cancelButton;
-      this.ClientSize = new System.Drawing.Size(269, 154);
-      this.ControlBox = false;
-      this.Controls.Add(this.cancelButton);
-      this.Controls.Add(this.okButton);
-      this.Controls.Add(this.variableNamesCombo);
-      this.Controls.Add(this.variableNameLabel);
-      this.Controls.Add(this.newValueLabel);
-      this.Controls.Add(this.newValueTextBox);
-      this.Controls.Add(this.oldValueTextBox);
-      this.Controls.Add(this.originalValueLabel);
-      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
-      this.MaximizeBox = false;
-      this.MinimizeBox = false;
-      this.Name = "ValueChangeDialog";
-      this.ShowIcon = false;
-      this.ShowInTaskbar = false;
-      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
-      this.Text = "Change Value or Weight";
-      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ValueChangeDialog_KeyDown);
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-
-    private System.Windows.Forms.Label originalValueLabel;
-    private System.Windows.Forms.TextBox oldValueTextBox;
-    private System.Windows.Forms.Label newValueLabel;
-    private System.Windows.Forms.ErrorProvider errorProvider;
-    private System.Windows.Forms.Label variableNameLabel;
-    private System.Windows.Forms.Button cancelButton;
-    private System.Windows.Forms.Button okButton;
-    public System.Windows.Forms.TextBox newValueTextBox;
-    public System.Windows.Forms.ComboBox variableNamesCombo;
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeChangeValueDialog.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeNodeChangeValueDialog.cs	(revision 8950)
+++ 	(revision )
@@ -1,139 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.ComponentModel;
-using System.Text;
-using System.Windows.Forms;
-using HeuristicLab.Data;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
-  public partial class ValueChangeDialog : Form {
-    private ISymbolicExpressionTreeNode content;
-    public ISymbolicExpressionTreeNode Content {
-      get { return content; }
-      set {
-        if (InvokeRequired)
-          Invoke(new Action<SymbolicExpressionTreeNode>(x => content = x), value);
-        else
-          content = value;
-      }
-    }
-
-    public ValueChangeDialog() {
-      InitializeComponent();
-      oldValueTextBox.TabStop = false; // cannot receive focus using tab key
-    }
-
-    public void SetContent(ISymbolicExpressionTreeNode content) {
-      Content = content;
-      if (Content is VariableTreeNode) {
-        this.Text = "Change variable name or weight";
-        var variable = Content as VariableTreeNode;
-        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(variable.Weight, 4).ToString();
-        // add a dropbox containing all the available variable names
-        variableNameLabel.Visible = true;
-        variableNamesCombo.Visible = true;
-        foreach (var name in variable.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
-        variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variable.VariableName);
-      } else if (Content is ConstantTreeNode) {
-        this.Text = "Change constant value";
-        var constant = Content as ConstantTreeNode;
-        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(constant.Value, 4).ToString();
-      }
-    }
-
-    #region text box validation and events
-    private void newValueTextBox_Validating(object sender, CancelEventArgs e) {
-      string errorMessage;
-      if (!ValidateNewValue(newValueTextBox.Text, out errorMessage)) {
-        e.Cancel = true;
-        errorProvider.SetError(newValueTextBox, errorMessage);
-        newValueTextBox.SelectAll();
-      }
-    }
-
-    private void newValueTextBox_Validated(object sender, EventArgs e) {
-      errorProvider.SetError(newValueTextBox, string.Empty);
-    }
-
-    private static bool ValidateNewValue(string value, out string errorMessage) {
-      double val;
-      bool valid = double.TryParse(value, out val);
-      errorMessage = string.Empty;
-      if (!valid) {
-        var sb = new StringBuilder();
-        sb.Append("Invalid Value (Valid Value Format: \"");
-        sb.Append(FormatPatterns.GetDoubleFormatPattern());
-        sb.Append("\")");
-        errorMessage = sb.ToString();
-      }
-      return valid;
-    }
-    #endregion
-
-    #region combo box validation and events
-    private void variableNamesCombo_Validating(object sender, CancelEventArgs e) {
-      if (!(Content is VariableTreeNode)) return;
-      if (variableNamesCombo.Items.Contains(variableNamesCombo.SelectedItem)) return;
-      e.Cancel = true;
-      errorProvider.SetError(variableNamesCombo, "Invalid variable name");
-      variableNamesCombo.SelectAll();
-    }
-
-    private void variableNamesCombo_Validated(object sender, EventArgs e) {
-      errorProvider.SetError(variableNamesCombo, String.Empty);
-    }
-    #endregion
-    // proxy handler passing key strokes to the parent control
-    private void childControl_KeyDown(object sender, KeyEventArgs e) {
-      ValueChangeDialog_KeyDown(sender, e);
-    }
-
-    private void ValueChangeDialog_KeyDown(object sender, KeyEventArgs e) {
-      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) {
-        if (!ValidateChildren()) return;
-        OnDialogValidated(this, e); // emit validated effect
-        Close();
-      }
-    }
-
-    public event EventHandler DialogValidated;
-    private void OnDialogValidated(object sender, EventArgs e) {
-      var dialogValidated = DialogValidated;
-      if (dialogValidated != null)
-        dialogValidated(sender, e);
-    }
-
-    private void cancelButton_Click(object sender, EventArgs e) {
-      Close();
-    }
-
-    private void okButton_Click(object sender, EventArgs e) {
-      if (ValidateChildren()) {
-        OnDialogValidated(this, e);
-        Close();
-      }
-    }
-
-  }
-}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs	(revision 8980)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.Designer.cs	(revision 8980)
@@ -0,0 +1,191 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Problems.DataAnalysis.Symbolic.Views {
+  partial class VariableNodeEditDialog {
+    /// <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) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Windows Form 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.components = new System.ComponentModel.Container();
+      this.originalValueLabel = new System.Windows.Forms.Label();
+      this.oldValueTextBox = new System.Windows.Forms.TextBox();
+      this.newValueTextBox = new System.Windows.Forms.TextBox();
+      this.newValueLabel = new System.Windows.Forms.Label();
+      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.variableNameLabel = new System.Windows.Forms.Label();
+      this.variableNamesCombo = new System.Windows.Forms.ComboBox();
+      this.okButton = new System.Windows.Forms.Button();
+      this.cancelButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // originalValueLabel
+      // 
+      this.originalValueLabel.AutoSize = true;
+      this.originalValueLabel.Location = new System.Drawing.Point(12, 48);
+      this.originalValueLabel.Name = "originalValueLabel";
+      this.originalValueLabel.Size = new System.Drawing.Size(72, 13);
+      this.originalValueLabel.TabIndex = 2;
+      this.originalValueLabel.Text = "Original Value";
+      // 
+      // oldValueTextBox
+      // 
+      this.oldValueTextBox.Location = new System.Drawing.Point(123, 45);
+      this.oldValueTextBox.Name = "oldValueTextBox";
+      this.oldValueTextBox.ReadOnly = true;
+      this.oldValueTextBox.Size = new System.Drawing.Size(131, 20);
+      this.oldValueTextBox.TabIndex = 3;
+      // 
+      // newValueTextBox
+      // 
+      this.newValueTextBox.Location = new System.Drawing.Point(123, 82);
+      this.newValueTextBox.Name = "newValueTextBox";
+      this.newValueTextBox.Size = new System.Drawing.Size(131, 20);
+      this.newValueTextBox.TabIndex = 0;
+      this.newValueTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
+      this.newValueTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.newValueTextBox_Validating);
+      this.newValueTextBox.Validated += new System.EventHandler(this.newValueTextBox_Validated);
+      // 
+      // newValueLabel
+      // 
+      this.newValueLabel.AutoSize = true;
+      this.newValueLabel.Location = new System.Drawing.Point(12, 85);
+      this.newValueLabel.Name = "newValueLabel";
+      this.newValueLabel.Size = new System.Drawing.Size(59, 13);
+      this.newValueLabel.TabIndex = 5;
+      this.newValueLabel.Text = "New Value";
+      // 
+      // errorProvider
+      // 
+      this.errorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.errorProvider.ContainerControl = this;
+      this.errorProvider.RightToLeft = true;
+      // 
+      // variableNameLabel
+      // 
+      this.variableNameLabel.AutoSize = true;
+      this.variableNameLabel.Location = new System.Drawing.Point(12, 12);
+      this.variableNameLabel.Name = "variableNameLabel";
+      this.variableNameLabel.Size = new System.Drawing.Size(76, 13);
+      this.variableNameLabel.TabIndex = 6;
+      this.variableNameLabel.Text = "Variable Name";
+      this.variableNameLabel.Visible = false;
+      // 
+      // variableNamesCombo
+      // 
+      this.variableNamesCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.variableNamesCombo.FormattingEnabled = true;
+      this.variableNamesCombo.Location = new System.Drawing.Point(123, 9);
+      this.variableNamesCombo.Name = "variableNamesCombo";
+      this.variableNamesCombo.Size = new System.Drawing.Size(131, 21);
+      this.variableNamesCombo.TabIndex = 7;
+      this.variableNamesCombo.Visible = false;
+      this.variableNamesCombo.KeyDown += new System.Windows.Forms.KeyEventHandler(this.childControl_KeyDown);
+      this.variableNamesCombo.Validating += new System.ComponentModel.CancelEventHandler(this.variableNamesCombo_Validating);
+      this.variableNamesCombo.Validated += new System.EventHandler(this.variableNamesCombo_Validated);
+      // 
+      // okButton
+      // 
+      this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
+      this.okButton.Location = new System.Drawing.Point(15, 119);
+      this.okButton.Name = "okButton";
+      this.okButton.Size = new System.Drawing.Size(75, 23);
+      this.okButton.TabIndex = 8;
+      this.okButton.Text = "OK";
+      this.okButton.UseVisualStyleBackColor = true;
+      this.okButton.Click += new System.EventHandler(this.okButton_Click);
+      // 
+      // cancelButton
+      // 
+      this.cancelButton.CausesValidation = false;
+      this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+      this.cancelButton.Location = new System.Drawing.Point(179, 119);
+      this.cancelButton.Name = "cancelButton";
+      this.cancelButton.Size = new System.Drawing.Size(75, 23);
+      this.cancelButton.TabIndex = 9;
+      this.cancelButton.Text = "Cancel";
+      this.cancelButton.UseVisualStyleBackColor = true;
+      this.cancelButton.Click += new System.EventHandler(this.cancelButton_Click);
+      // 
+      // VariableNodeEditDialog
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.AutoSize = true;
+      this.CancelButton = this.cancelButton;
+      this.ClientSize = new System.Drawing.Size(269, 154);
+      this.ControlBox = false;
+      this.Controls.Add(this.cancelButton);
+      this.Controls.Add(this.okButton);
+      this.Controls.Add(this.variableNamesCombo);
+      this.Controls.Add(this.variableNameLabel);
+      this.Controls.Add(this.newValueLabel);
+      this.Controls.Add(this.newValueTextBox);
+      this.Controls.Add(this.oldValueTextBox);
+      this.Controls.Add(this.originalValueLabel);
+      this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
+      this.MaximizeBox = false;
+      this.MinimizeBox = false;
+      this.Name = "VariableNodeEditDialog";
+      this.ShowIcon = false;
+      this.ShowInTaskbar = false;
+      this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+      this.Text = "Change Value or Weight";
+      this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ValueChangeDialog_KeyDown);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Label originalValueLabel;
+    private System.Windows.Forms.TextBox oldValueTextBox;
+    private System.Windows.Forms.Label newValueLabel;
+    private System.Windows.Forms.ErrorProvider errorProvider;
+    private System.Windows.Forms.Label variableNameLabel;
+    private System.Windows.Forms.Button cancelButton;
+    private System.Windows.Forms.Button okButton;
+    public System.Windows.Forms.TextBox newValueTextBox;
+    public System.Windows.Forms.ComboBox variableNamesCombo;
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs	(revision 8980)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Symbolic.Views/3.4/TreeEditDialogs/SymbolicExpressionTreeVariableNodeEditDialog.cs	(revision 8980)
@@ -0,0 +1,143 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ComponentModel;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.Views {
+  public partial class VariableNodeEditDialog : Form {
+    private VariableTreeNode variableTreeNode;
+    public VariableTreeNode NewNode {
+      get { return variableTreeNode; }
+      set {
+        if (InvokeRequired)
+          Invoke(new Action<SymbolicExpressionTreeNode>(x => variableTreeNode = (VariableTreeNode)x), value);
+        else
+          variableTreeNode = value;
+      }
+    }
+
+    public VariableNodeEditDialog(ISymbolicExpressionTreeNode node) {
+      InitializeComponent();
+      oldValueTextBox.TabStop = false; // cannot receive focus using tab key
+
+      NewNode = (VariableTreeNode)node; // will throw an invalid cast exception if node is not of the correct type
+      InitializeFields();
+    }
+
+    private void InitializeFields() {
+      if (NewNode == null)
+        throw new ArgumentException("Node is not a constant.");
+      else {
+        this.Text = "Edit variable";
+        newValueTextBox.Text = oldValueTextBox.Text = Math.Round(variableTreeNode.Weight, 4).ToString();
+        // add a dropbox containing all the available variable names
+        variableNameLabel.Visible = true;
+        variableNamesCombo.Visible = true;
+        foreach (var name in variableTreeNode.Symbol.VariableNames) variableNamesCombo.Items.Add(name);
+        variableNamesCombo.SelectedIndex = variableNamesCombo.Items.IndexOf(variableTreeNode.VariableName);
+      }
+    }
+
+    #region text box validation and events
+    private void newValueTextBox_Validating(object sender, CancelEventArgs e) {
+      string errorMessage;
+      if (!ValidateNewValue(newValueTextBox.Text, out errorMessage)) {
+        e.Cancel = true;
+        errorProvider.SetError(newValueTextBox, errorMessage);
+        newValueTextBox.SelectAll();
+      }
+    }
+
+    private void newValueTextBox_Validated(object sender, EventArgs e) {
+      errorProvider.SetError(newValueTextBox, string.Empty);
+    }
+
+    private static bool ValidateNewValue(string value, out string errorMessage) {
+      double val;
+      bool valid = double.TryParse(value, out val);
+      errorMessage = string.Empty;
+      if (!valid) {
+        var sb = new StringBuilder();
+        sb.Append("Invalid Value (Valid Value Format: \"");
+        sb.Append(FormatPatterns.GetDoubleFormatPattern());
+        sb.Append("\")");
+        errorMessage = sb.ToString();
+      }
+      return valid;
+    }
+    #endregion
+
+    #region combo box validation and events
+    private void variableNamesCombo_Validating(object sender, CancelEventArgs e) {
+      if (variableNamesCombo.Items.Contains(variableNamesCombo.SelectedItem)) return;
+      e.Cancel = true;
+      errorProvider.SetError(variableNamesCombo, "Invalid variable name");
+      variableNamesCombo.SelectAll();
+    }
+
+    private void variableNamesCombo_Validated(object sender, EventArgs e) {
+      errorProvider.SetError(variableNamesCombo, String.Empty);
+    }
+    #endregion
+    // proxy handler passing key strokes to the parent control
+    private void childControl_KeyDown(object sender, KeyEventArgs e) {
+      ValueChangeDialog_KeyDown(sender, e);
+    }
+
+    private void ValueChangeDialog_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return)) {
+        if (!ValidateChildren()) return;
+        OnDialogValidated(this, e); // emit validated effect
+        Close();
+      }
+    }
+
+    public event EventHandler DialogValidated;
+    private void OnDialogValidated(object sender, EventArgs e) {
+      double weight = double.Parse(newValueTextBox.Text);
+      var variableName = (string)variableNamesCombo.SelectedItem;
+      // we impose an extra validation condition: that the weight/value be different than the original ones
+      if (variableTreeNode.Weight.Equals(weight) && variableTreeNode.VariableName.Equals(variableName)) return;
+      variableTreeNode.Weight = weight;
+      variableTreeNode.VariableName = variableName;
+      DialogResult = DialogResult.OK;
+      var dialogValidated = DialogValidated;
+      if (dialogValidated != null)
+        dialogValidated(sender, e);
+    }
+
+    private void cancelButton_Click(object sender, EventArgs e) {
+      Close();
+    }
+
+    private void okButton_Click(object sender, EventArgs e) {
+      if (ValidateChildren()) {
+        OnDialogValidated(this, e);
+        Close();
+      }
+    }
+  }
+}
