Index: branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/HashExtensions.cs
===================================================================
--- branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/HashExtensions.cs	(revision 16304)
+++ branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/HashExtensions.cs	(revision 16306)
@@ -35,5 +35,7 @@
       public ulong CalculatedHashValue; // the calculated hash value (taking into account the children hash values)
 
-      public Action<HashNode<T>[], int> Simplify;
+      public delegate void SimplifyAction(ref HashNode<T>[] nodes, int i);
+      public SimplifyAction Simplify;
+
       public IComparer<T> Comparer;
 
@@ -108,5 +110,5 @@
           continue;
         }
-        node.Simplify?.Invoke(reduced, i);
+        node.Simplify?.Invoke(ref reduced, i);
       }
       // detect if anything was simplified
Index: branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/SymbolicExpressionTreeHash.cs
===================================================================
--- branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/SymbolicExpressionTreeHash.cs	(revision 16304)
+++ branches/2915-AbsoluteSymbol/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Hashing/SymbolicExpressionTreeHash.cs	(revision 16306)
@@ -227,8 +227,9 @@
     }
 
-    public static void SimplifyAddition(HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
+    public static void SimplifyAddition(ref HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
       // simplify additions of terms by eliminating terms with the same symbol and hash
       var children = nodes.IterateChildren(i);
 
+      // we always assume the child nodes are sorted
       var curr = children[0];
       var node = nodes[i];
@@ -236,7 +237,5 @@
       foreach (var j in children.Skip(1)) {
         if (nodes[j] == nodes[curr]) {
-          for (int k = j - nodes[j].Size; k <= j; ++k) {
-            nodes[k].Enabled = false;
-          }
+          nodes.SetEnabled(j, false);
           node.Arity--;
         } else {
@@ -250,5 +249,5 @@
 
     // simplify multiplications by reducing constants and div terms  
-    public static void SimplifyMultiplication(HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
+    public static void SimplifyMultiplication(ref HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
       var node = nodes[i];
       var children = nodes.IterateChildren(i);
@@ -298,9 +297,11 @@
     }
 
-    public static void SimplifyDivision(HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
+    public static void SimplifyDivision(ref HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
       var node = nodes[i];
       var children = nodes.IterateChildren(i);
 
-      if (children.All(x => nodes[x].Data.Symbol is Constant)) {
+      var tmp = nodes;
+
+      if (children.All(x => tmp[x].Data.Symbol is Constant)) {
         var v = ((ConstantTreeNode)nodes[children.First()].Data).Value;
         if (node.Arity == 1) {
@@ -333,5 +334,5 @@
     }
 
-    public static void SimplifyUnaryNode(HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
+    public static void SimplifyUnaryNode(ref HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
       // check if the child of the unary node is a constant, then the whole node can be simplified
       var parent = nodes[i];
@@ -348,7 +349,8 @@
     }
 
-    public static void SimplifyBinaryNode(HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
+    public static void SimplifyBinaryNode(ref HashNode<ISymbolicExpressionTreeNode>[] nodes, int i) {
       var children = nodes.IterateChildren(i);
-      if (children.All(x => nodes[x].Data.Symbol is Constant)) {
+      var tmp = nodes;
+      if (children.All(x => tmp[x].Data.Symbol is Constant)) {
         foreach (var j in children) {
           nodes[j].Enabled = false;
