Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.csproj	(revision 7832)
@@ -162,7 +162,18 @@
     <Compile Include="Moves\ChangeNodeTypeMove.cs" />
     <Compile Include="Moves\ChangeNodeTypeMoveMaker.cs" />
+    <Compile Include="Moves\ChangeNodeTypeMoveSoftTabuCriterion.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="Moves\ChangeNodeTypeMultiMoveGenerator.cs" />
+    <Compile Include="Moves\ReplaceBranchMoveTabuMaker.cs" />
+    <Compile Include="Moves\ReplaceBranchMoveSoftTabuCriterion.cs" />
+    <Compile Include="Moves\ReplaceBranchMoveMaker.cs" />
+    <Compile Include="Moves\ReplaceBranchMove.cs" />
+    <Compile Include="Moves\SymbolicExpressionTreeMoveAttribute.cs" />
     <Compile Include="Moves\ShakeMultiMoveGenerator.cs" />
     <Compile Include="Moves\ShakeMoveGenerator.cs" />
+    <Compile Include="Moves\ChangeNodeTypeMoveHardTabuCriterion.cs" />
+    <Compile Include="Moves\ChangeNodeTypeMoveTabuMaker.cs" />
+    <Compile Include="Moves\ChangeNodeTypeMoveAbsoluteAttribute.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="SymbolicExpressionGrammarBase.cs" />
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeMoveOperator.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeMoveOperator.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Interfaces/Operators/ISymbolicExpressionTreeMoveOperator.cs	(revision 7832)
@@ -25,5 +25,5 @@
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   public interface ISymbolicExpressionTreeMoveOperator : ISymbolicExpressionTreeOperator, IMoveOperator {
-    ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter { get; }
+    ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter { get; }
   }
 }
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveAbsoluteAttribute.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveAbsoluteAttribute.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveAbsoluteAttribute.cs	(revision 7832)
@@ -0,0 +1,48 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ChangeNodeTypeMoveAbsoluteAttribute", "")]
+  [StorableClass]
+  public class ChangeNodeTypeMoveAbsoluteAttribute : SymbolicExpressionTreeMoveAttribute {
+    [Storable]
+    public int[] Path { get; private set; }
+
+    [StorableConstructor]
+    protected ChangeNodeTypeMoveAbsoluteAttribute(bool deserializing) : base(deserializing) { }
+    protected ChangeNodeTypeMoveAbsoluteAttribute(ChangeNodeTypeMoveAbsoluteAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.Path = (int[])original.Path.Clone();
+    }
+    public ChangeNodeTypeMoveAbsoluteAttribute(int[] path, double moveQuality)
+      : base(moveQuality) {
+      Path = path;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChangeNodeTypeMoveAbsoluteAttribute(this, cloner);
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveGenerator.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveGenerator.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveGenerator.cs	(revision 7832)
@@ -30,7 +30,7 @@
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  [Item("ChangeNodeTypeMoveGenerator", "Operator that generates moves for changing the symbol of a single symbolic expression tree node.")]
+  [Item("ChangeNodeTypeExhaustiveMoveGenerator", "Operator that generates moves for changing the symbol of a single symbolic expression tree node.")]
   [StorableClass]
-  public class ChangeNodeTypeMoveGenerator : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, IMoveGenerator, IStochasticOperator {
+  public class ChangeNodeTypeMoveGenerator : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, IExhaustiveMoveGenerator, IStochasticOperator {
     public override bool CanChangeName {
       get { return false; }
@@ -39,6 +39,6 @@
       get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
     }
-    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
     }
     public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
@@ -55,5 +55,5 @@
       : base() {
       Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
-      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
       Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The moves that should be generated in subscopes."));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
@@ -66,5 +66,5 @@
 
     public override IOperation Apply() {
-      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       var moves = GenerateMoves(tree);
       string moveParameterName = ChangeNodeTypeMoveParameter.ActualName;
@@ -82,5 +82,5 @@
     }
 
-    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(SymbolicExpressionTree tree) {
+    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(ISymbolicExpressionTree tree) {
       var g = tree.Root.Grammar;
       return (from parent in tree.Root.GetSubtree(0).IterateNodesPrefix()
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveHardTabuCriterion.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveHardTabuCriterion.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveHardTabuCriterion.cs	(revision 7832)
@@ -0,0 +1,180 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ChangeNodeTypeMoveHardTabuCriterion", "")]
+  [StorableClass]
+  public class ChangeNodeTypeMoveHardTabuCriterion : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
+      get { return (LookupParameter<ChangeNodeTypeMove>)Parameters["ChangeNodeTypeMove"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (LookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ChangeNodeTypeMoveHardTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected ChangeNodeTypeMoveHardTabuCriterion(ChangeNodeTypeMoveHardTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public ChangeNodeTypeMoveHardTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The solution as permutation."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChangeNodeTypeMoveHardTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      ChangeNodeTypeMove move = ChangeNodeTypeMoveParameter.ActualValue;
+      ISymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
+      bool isTabu = true;
+      //int length = permutation.Length;
+      //double moveQuality = MoveQualityParameter.ActualValue.Value;
+      //bool maximization = MaximizationParameter.ActualValue.Value;
+      //bool useAspiration = UseAspirationCriterion.Value;
+      //bool isTabu = false;
+
+      //if (permutation.PermutationType == PermutationTypes.Absolute) {
+      //  int count = move.Index2 - move.Index1 + 1;
+      //  int[] numbers = new int[count];
+      //  for (int i = move.Index1; i <= move.Index2; i++)
+      //    numbers[i - move.Index1] = permutation[i];
+
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) { // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay
+
+      //        for (int i = 0; i < count; i++) {
+      //          for (int j = 0; j < attribute.Number.Length; j++) {
+      //            if (attribute.Number[j] == numbers[i]) {
+      //              isTabu = true;
+      //              break;
+      //            }
+      //          }
+      //          if (isTabu) break;
+      //        }
+      //      }
+      //    }
+      //    if (isTabu) break;
+      //  }
+      //} else {
+      //  int E1S = permutation.GetCircular(move.Index1 - 1);
+      //  int E1T = permutation[move.Index1];
+      //  int E2S = permutation[move.Index2];
+      //  int E2T = permutation.GetCircular(move.Index2 + 1);
+      //  int E3S, E3T;
+      //  if (move.Index3 > move.Index1) {
+      //    E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+      //    E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      //  } else {
+      //    E3S = permutation.GetCircular(move.Index3 - 1);
+      //    E3T = permutation[move.Index3];
+      //  }
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) {
+
+      //        if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+      //          if (// if previously added Edge3Source-Edge1Target is deleted
+      //            attribute.Edge3Source == E1S && attribute.Edge1Target == E1T || attribute.Edge3Source == E1T && attribute.Edge1Target == E1S
+      //            || attribute.Edge3Source == E2S && attribute.Edge1Target == E2T || attribute.Edge3Source == E2T && attribute.Edge1Target == E2S
+      //            || attribute.Edge3Source == E3S && attribute.Edge1Target == E3T || attribute.Edge3Source == E3T && attribute.Edge1Target == E3S
+      //            // if previously added Edge2Source-Edge3Target is deleted
+      //            || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T || attribute.Edge2Source == E1T && attribute.Edge3Target == E1S
+      //            || attribute.Edge2Source == E2S && attribute.Edge3Target == E2T || attribute.Edge2Source == E2T && attribute.Edge3Target == E2S
+      //            || attribute.Edge2Source == E3S && attribute.Edge3Target == E3T || attribute.Edge2Source == E3T && attribute.Edge3Target == E3S
+      //            // if previously added Edge1Source-Edge2Target is deleted
+      //            || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T || attribute.Edge1Source == E1T && attribute.Edge2Target == E1S
+      //            || attribute.Edge1Source == E2S && attribute.Edge2Target == E2T || attribute.Edge1Source == E2T && attribute.Edge2Target == E2S
+      //            || attribute.Edge1Source == E3S && attribute.Edge2Target == E3T || attribute.Edge1Source == E3T && attribute.Edge2Target == E3S) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        } else {
+      //          if (// if previously added Edge3Source-Edge1Target is deleted
+      //            attribute.Edge3Source == E1S && attribute.Edge1Target == E1T
+      //            || attribute.Edge3Source == E2S && attribute.Edge1Target == E2T
+      //            || attribute.Edge3Source == E3S && attribute.Edge1Target == E3T
+      //            // if previously added Edge2Source-Edge3Target is deleted
+      //            || attribute.Edge2Source == E1S && attribute.Edge3Target == E1T
+      //            || attribute.Edge2Source == E2S && attribute.Edge3Target == E2T
+      //            || attribute.Edge2Source == E3S && attribute.Edge3Target == E3T
+      //            // if previously added Edge1Source-Edge2Target is deleted
+      //            || attribute.Edge1Source == E1S && attribute.Edge2Target == E1T
+      //            || attribute.Edge1Source == E2S && attribute.Edge2Target == E2T
+      //            || attribute.Edge1Source == E3S && attribute.Edge2Target == E3T) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        }
+      //      }
+      //    }
+      //  }
+      //}
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveMaker.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveMaker.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveMaker.cs	(revision 7832)
@@ -45,6 +45,6 @@
       get { return (ILookupParameter<ChangeNodeTypeMove>)Parameters["ChangeNodeTypeMove"]; }
     }
-    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
     }
 
@@ -57,5 +57,5 @@
       Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The move to evaluate."));
       Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
-      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree on which the move should be applied."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree on which the move should be applied."));
     }
 
@@ -66,5 +66,5 @@
     public override IOperation Apply() {
       ChangeNodeTypeMove move = ChangeNodeTypeMoveParameter.ActualValue;
-      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       DoubleValue moveQuality = MoveQualityParameter.ActualValue;
       DoubleValue quality = QualityParameter.ActualValue;
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveSoftTabuCriterion.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveSoftTabuCriterion.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveSoftTabuCriterion.cs	(revision 7832)
@@ -0,0 +1,207 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ChangeNodeTypeMoveSoftTabuCriterion", @"")]
+  [StorableClass]
+  public class ChangeNodeTypeMoveSoftTabuCriterion : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
+      get { return (LookupParameter<ChangeNodeTypeMove>)Parameters["ChangeNodeTypeMove"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (LookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ChangeNodeTypeMoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected ChangeNodeTypeMoveSoftTabuCriterion(ChangeNodeTypeMoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public ChangeNodeTypeMoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The solution as symbolic expression tree."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChangeNodeTypeMoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      var move = ChangeNodeTypeMoveParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      bool isTabu = true;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+
+      List<int> path = new List<int>();
+      path.Add(move.SubtreeIndex);
+      var parent = move.Parent.Parent;
+      var child = move.Parent;
+      while (parent != null) {
+        path.Add(parent.IndexOfSubtree(child));
+        child = parent;
+        parent = parent.Parent;
+      }
+      path.Reverse();
+
+      isTabu = false;
+      for (int i = 0; i < tabuList.Count && isTabu == false; i++) {
+        var tabuAttribute = tabuList[i];
+        var absTabuAttribute = tabuAttribute as ChangeNodeTypeMoveAbsoluteAttribute;
+        if (!useAspiration
+              || maximization && moveQuality <= absTabuAttribute.MoveQuality
+              || !maximization && moveQuality >= absTabuAttribute.MoveQuality) {
+          if (absTabuAttribute != null && absTabuAttribute.Path.Length == path.Count) {
+            isTabu = true;
+            for (int j = 0; j < path.Count; j++) {
+              if (absTabuAttribute.Path[j] != path[j]) {
+                isTabu = false;
+                break;
+              }
+            }
+          }
+        }
+      }
+      //int length = permutation.Length;
+      //double moveQuality = MoveQualityParameter.ActualValue.Value;
+      //bool maximization = MaximizationParameter.ActualValue.Value;
+      //bool useAspiration = UseAspirationCriterion.Value;
+      //bool isTabu = false;
+
+      //if (permutation.PermutationType == PermutationTypes.Absolute) {
+      //  int count = move.Index2 - move.Index1 + 1;
+      //  int[] numbers = new int[count];
+      //  for (int i = move.Index1; i <= move.Index2; i++)
+      //    numbers[i - move.Index1] = permutation[i];
+
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) { // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay
+
+      //        for (int i = 0; i < count; i++) {
+      //          for (int j = 0; j < attribute.Number.Length; j++) {
+      //            if (attribute.Number[j] == numbers[i] && attribute.OldPosition + j == move.Index3 + i) {
+      //              isTabu = true;
+      //              break;
+      //            }
+      //          }
+      //          if (isTabu) break;
+      //        }
+      //      }
+      //    }
+      //    if (isTabu) break;
+      //  }
+      //} else {
+      //  int E1S = permutation.GetCircular(move.Index1 - 1);
+      //  int E1T = permutation[move.Index1];
+      //  int E2S = permutation[move.Index2];
+      //  int E2T = permutation.GetCircular(move.Index2 + 1);
+      //  int E3S, E3T;
+      //  if (move.Index3 > move.Index1) {
+      //    E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+      //    E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      //  } else {
+      //    E3S = permutation.GetCircular(move.Index3 - 1);
+      //    E3T = permutation[move.Index3];
+      //  }
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) {
+
+      //        // if previously deleted Edge1Source-Target is readded
+      //        if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+      //          if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T || attribute.Edge1Source == E1T && attribute.Edge1Target == E3S
+      //            || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T || attribute.Edge1Source == E3T && attribute.Edge1Target == E2S
+      //            // if previously deleted Edge2Source-Target is readded
+      //            || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T || attribute.Edge2Source == E1T && attribute.Edge2Target == E3S
+      //            || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T || attribute.Edge2Source == E3T && attribute.Edge2Target == E2S
+      //            // if previously deleted Edge3Source-Target is readded
+      //            || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T || attribute.Edge3Source == E1T && attribute.Edge3Target == E3S
+      //            || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T || attribute.Edge3Source == E3T && attribute.Edge3Target == E2S) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        } else {
+      //          if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T
+      //            || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T
+      //            // if previously deleted Edge2Source-Target is readded
+      //            || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T
+      //            || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T
+      //            // if previously deleted Edge3Source-Target is readded
+      //            || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T
+      //            || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        }
+      //      }
+      //    }
+      //  }
+      //}
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveTabuMaker.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveTabuMaker.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMoveTabuMaker.cs	(revision 7832)
@@ -0,0 +1,72 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ChangeNodeTypeMoveTabuMaker", "")]
+  [StorableClass]
+  public class ChangeNodeTypeMoveTabuMaker : TabuMaker, ISymbolicExpressionTreeMoveOperator {
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+    public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
+      get { return (LookupParameter<ChangeNodeTypeMove>)Parameters["ChangeNodeTypeMove"]; }
+    }
+
+    [StorableConstructor]
+    protected ChangeNodeTypeMoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected ChangeNodeTypeMoveTabuMaker(ChangeNodeTypeMoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public ChangeNodeTypeMoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The move that was made."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The solution as symbolic expression tree."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ChangeNodeTypeMoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      var move = ChangeNodeTypeMoveParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+
+      List<int> path = new List<int>();
+      path.Add(move.SubtreeIndex);
+      var parent = move.Parent.Parent;
+      var child = move.Parent;
+      while (parent != null) {
+        path.Add(parent.IndexOfSubtree(child));
+        child = parent;
+        parent = parent.Parent;
+      }
+      path.Reverse();
+      return new ChangeNodeTypeMoveAbsoluteAttribute(path.ToArray(), baseQuality);
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMultiMoveGenerator.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMultiMoveGenerator.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ChangeNodeTypeMultiMoveGenerator.cs	(revision 7832)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -46,6 +45,6 @@
       set { SampleSizeParameter.Value = value; }
     }
-    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
     }
     public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
@@ -64,5 +63,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
 
-      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
       Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The moves that should be generated in subscopes."));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
@@ -75,6 +74,7 @@
 
     public override IOperation Apply() {
-      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
-      var moves = ChangeNodeTypeMoveGenerator.GenerateMoves(tree).ToArray();
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+
+
       string moveParameterName = ChangeNodeTypeMoveParameter.ActualName;
       var moveScopes = new List<Scope>();
@@ -82,9 +82,7 @@
       int n = SampleSizeParameter.ActualValue.Value;
 
-      var rand = Enumerable.Range(0, moves.Length).Select(i => random.NextDouble()).ToArray();
-      Array.Sort(rand, moves);
-      n = Math.Min(n, moves.Length);
+      var moves = GenerateMoves(tree, random, n);
 
-      foreach (var m in moves.Take(n)) {
+      foreach (var m in moves) {
         if (m.NewChild.HasLocalParameters)
           m.NewChild.ResetLocalParameters(random);
@@ -96,4 +94,27 @@
       return base.Apply();
     }
+
+    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(ISymbolicExpressionTree tree, IRandom random, int n) {
+      int count = 0;
+      var g = tree.Root.Grammar;
+      var possibleChildren = (from parent in tree.Root.GetSubtree(0).IterateNodesPrefix()
+                              from i in Enumerable.Range(0, parent.SubtreeCount)
+                              from s in g.GetAllowedChildSymbols(parent.Symbol, i)
+                              where s.Enabled
+                              where s.InitialFrequency > 0.0
+                              let currentChild = parent.GetSubtree(i)
+                              where s.MinimumArity >= currentChild.SubtreeCount
+                              where s.MaximumArity <= currentChild.SubtreeCount
+                              where (from j in Enumerable.Range(0, currentChild.SubtreeCount)
+                                     let childOfChild = currentChild.GetSubtree(j)
+                                     select g.IsAllowedChildSymbol(s, childOfChild.Symbol, j)).All(p => p)
+                              select new { parent, i, s }).ToArray();
+      if (possibleChildren.Length < n) n = possibleChildren.Length;
+      while (count < n) {
+        var selected = possibleChildren[random.Next(possibleChildren.Length)];
+        yield return new ChangeNodeTypeMove(tree, selected.parent, selected.i, selected.s.CreateTreeNode());
+        count++;
+      }
+    }
   }
 }
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMove.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMove.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMove.cs	(revision 7832)
@@ -0,0 +1,65 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ReplaceBranchMove", "")]
+  [StorableClass]
+  public class ReplaceBranchMove : Item {
+
+    [Storable]
+    public ISymbolicExpressionTree Tree { get; set; }
+
+    [Storable]
+    public ISymbolicExpressionTreeNode Parent { get; set; }
+
+    [Storable]
+    public int SubtreeIndex { get; set; }
+
+    [Storable]
+    public ISymbolicExpressionTreeNode NewBranch { get; set; }
+
+
+    [StorableConstructor]
+    protected ReplaceBranchMove(bool deserializing) : base(deserializing) { }
+    protected ReplaceBranchMove(ReplaceBranchMove original, Cloner cloner)
+      : base(original, cloner) {
+      this.Tree = cloner.Clone(original.Tree);
+      this.SubtreeIndex = original.SubtreeIndex;
+      this.Parent = cloner.Clone(original.Parent);
+      this.NewBranch = cloner.Clone(original.NewBranch);
+    }
+    public ReplaceBranchMove(ISymbolicExpressionTree tree, ISymbolicExpressionTreeNode parent, int subtreeIndex, ISymbolicExpressionTreeNode newChild)
+      : base() {
+      this.Tree = tree;
+      this.SubtreeIndex = subtreeIndex;
+      this.Parent = parent;
+      this.NewBranch = newChild;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ReplaceBranchMove(this, cloner);
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveMaker.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveMaker.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveMaker.cs	(revision 7832)
@@ -0,0 +1,80 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ReplaceBranchMoveMaker", "")]
+  [StorableClass]
+  public class ReplaceBranchMoveMaker : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, IMoveMaker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ILookupParameter<ReplaceBranchMove> ReplaceBranchMoveParameter {
+      get { return (ILookupParameter<ReplaceBranchMove>)Parameters["ReplaceBranchMove"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+
+    [StorableConstructor]
+    protected ReplaceBranchMoveMaker(bool deserializing) : base(deserializing) { }
+    protected ReplaceBranchMoveMaker(ReplaceBranchMoveMaker original, Cloner cloner) : base(original, cloner) { }
+    public ReplaceBranchMoveMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<ReplaceBranchMove>("ReplaceBranchMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The relative quality of the move."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree on which the move should be applied."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ReplaceBranchMoveMaker(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var move = ReplaceBranchMoveParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      DoubleValue moveQuality = MoveQualityParameter.ActualValue;
+      DoubleValue quality = QualityParameter.ActualValue;
+
+      var newNode = (ISymbolicExpressionTreeNode)move.NewBranch.Clone();
+      move.Parent.RemoveSubtree(move.SubtreeIndex);
+      move.Parent.InsertSubtree(move.SubtreeIndex, newNode);
+
+      quality.Value = moveQuality.Value;
+
+      return base.Apply();
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveSoftTabuCriterion.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveSoftTabuCriterion.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveSoftTabuCriterion.cs	(revision 7832)
@@ -0,0 +1,207 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ReplaceBranchMoveSoftTabuCriterion", @"")]
+  [StorableClass]
+  public class ReplaceBranchMoveSoftTabuCriterion : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, ITabuChecker {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    public ILookupParameter<ReplaceBranchMove> ReplaceBranchMoveParameter {
+      get { return (LookupParameter<ReplaceBranchMove>)Parameters["ReplaceBranchMove"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (LookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+    public ILookupParameter<ItemList<IItem>> TabuListParameter {
+      get { return (ILookupParameter<ItemList<IItem>>)Parameters["TabuList"]; }
+    }
+    public ILookupParameter<BoolValue> MoveTabuParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["MoveTabu"]; }
+    }
+    public IValueLookupParameter<BoolValue> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+    public ILookupParameter<DoubleValue> MoveQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["MoveQuality"]; }
+    }
+    public ValueParameter<BoolValue> UseAspirationCriterionParameter {
+      get { return (ValueParameter<BoolValue>)Parameters["UseAspirationCriterion"]; }
+    }
+
+    public BoolValue UseAspirationCriterion {
+      get { return UseAspirationCriterionParameter.Value; }
+      set { UseAspirationCriterionParameter.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected ReplaceBranchMoveSoftTabuCriterion(bool deserializing) : base(deserializing) { }
+    protected ReplaceBranchMoveSoftTabuCriterion(ReplaceBranchMoveSoftTabuCriterion original, Cloner cloner) : base(original, cloner) { }
+    public ReplaceBranchMoveSoftTabuCriterion()
+      : base() {
+      Parameters.Add(new LookupParameter<ReplaceBranchMove>("ReplaceBranchMove", "The move to evaluate."));
+      Parameters.Add(new LookupParameter<BoolValue>("MoveTabu", "The variable to store if a move was tabu."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The solution as symbolic expression tree."));
+      Parameters.Add(new LookupParameter<ItemList<IItem>>("TabuList", "The tabu list."));
+      Parameters.Add(new ValueParameter<BoolValue>("UseAspirationCriterion", "Whether to use the aspiration criterion or not.", new BoolValue(true)));
+      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, else if it is a minimization problem."));
+      Parameters.Add(new LookupParameter<DoubleValue>("MoveQuality", "The quality of the current move."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ReplaceBranchMoveSoftTabuCriterion(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemList<IItem> tabuList = TabuListParameter.ActualValue;
+      var move = ReplaceBranchMoveParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      bool isTabu = true;
+      bool useAspiration = UseAspirationCriterion.Value;
+      bool maximization = MaximizationParameter.ActualValue.Value;
+      double moveQuality = MoveQualityParameter.ActualValue.Value;
+
+      List<int> path = new List<int>();
+      path.Add(move.SubtreeIndex);
+      var parent = move.Parent.Parent;
+      var child = move.Parent;
+      while (parent != null) {
+        path.Add(parent.IndexOfSubtree(child));
+        child = parent;
+        parent = parent.Parent;
+      }
+      path.Reverse();
+
+      isTabu = false;
+      for (int i = 0; i < tabuList.Count && isTabu == false; i++) {
+        var tabuAttribute = tabuList[i];
+        var absTabuAttribute = tabuAttribute as ChangeNodeTypeMoveAbsoluteAttribute;
+        if (!useAspiration
+              || maximization && moveQuality <= absTabuAttribute.MoveQuality
+              || !maximization && moveQuality >= absTabuAttribute.MoveQuality) {
+          if (absTabuAttribute != null && absTabuAttribute.Path.Length == path.Count) {
+            isTabu = true;
+            for (int j = 0; j < path.Count; j++) {
+              if (absTabuAttribute.Path[j] != path[j]) {
+                isTabu = false;
+                break;
+              }
+            }
+          }
+        }
+      }
+      //int length = permutation.Length;
+      //double moveQuality = MoveQualityParameter.ActualValue.Value;
+      //bool maximization = MaximizationParameter.ActualValue.Value;
+      //bool useAspiration = UseAspirationCriterion.Value;
+      //bool isTabu = false;
+
+      //if (permutation.PermutationType == PermutationTypes.Absolute) {
+      //  int count = move.Index2 - move.Index1 + 1;
+      //  int[] numbers = new int[count];
+      //  for (int i = move.Index1; i <= move.Index2; i++)
+      //    numbers[i - move.Index1] = permutation[i];
+
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveAbsoluteAttribute attribute = (tabuMove as TranslocationMoveAbsoluteAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) { // if the move quality is improving beyond what was recorded when the move in the tabu list was recorded the move is regarded as okay
+
+      //        for (int i = 0; i < count; i++) {
+      //          for (int j = 0; j < attribute.Number.Length; j++) {
+      //            if (attribute.Number[j] == numbers[i] && attribute.OldPosition + j == move.Index3 + i) {
+      //              isTabu = true;
+      //              break;
+      //            }
+      //          }
+      //          if (isTabu) break;
+      //        }
+      //      }
+      //    }
+      //    if (isTabu) break;
+      //  }
+      //} else {
+      //  int E1S = permutation.GetCircular(move.Index1 - 1);
+      //  int E1T = permutation[move.Index1];
+      //  int E2S = permutation[move.Index2];
+      //  int E2T = permutation.GetCircular(move.Index2 + 1);
+      //  int E3S, E3T;
+      //  if (move.Index3 > move.Index1) {
+      //    E3S = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1);
+      //    E3T = permutation.GetCircular(move.Index3 + move.Index2 - move.Index1 + 1);
+      //  } else {
+      //    E3S = permutation.GetCircular(move.Index3 - 1);
+      //    E3T = permutation[move.Index3];
+      //  }
+      //  foreach (IItem tabuMove in tabuList) {
+      //    TranslocationMoveRelativeAttribute attribute = (tabuMove as TranslocationMoveRelativeAttribute);
+      //    if (attribute != null) {
+      //      if (!useAspiration
+      //        || maximization && moveQuality <= attribute.MoveQuality
+      //        || !maximization && moveQuality >= attribute.MoveQuality) {
+
+      //        // if previously deleted Edge1Source-Target is readded
+      //        if (permutation.PermutationType == PermutationTypes.RelativeUndirected) {
+      //          if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T || attribute.Edge1Source == E1T && attribute.Edge1Target == E3S
+      //            || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T || attribute.Edge1Source == E3T && attribute.Edge1Target == E2S
+      //            // if previously deleted Edge2Source-Target is readded
+      //            || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T || attribute.Edge2Source == E1T && attribute.Edge2Target == E3S
+      //            || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T || attribute.Edge2Source == E3T && attribute.Edge2Target == E2S
+      //            // if previously deleted Edge3Source-Target is readded
+      //            || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T || attribute.Edge3Source == E1T && attribute.Edge3Target == E3S
+      //            || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T || attribute.Edge3Source == E3T && attribute.Edge3Target == E2S) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        } else {
+      //          if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T
+      //            || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T
+      //            // if previously deleted Edge2Source-Target is readded
+      //            || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T
+      //            || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T
+      //            // if previously deleted Edge3Source-Target is readded
+      //            || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T
+      //            || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T) {
+      //            isTabu = true;
+      //            break;
+      //          }
+      //        }
+      //      }
+      //    }
+      //  }
+      //}
+      MoveTabuParameter.ActualValue = new BoolValue(isTabu);
+      return base.Apply();
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveTabuMaker.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveTabuMaker.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ReplaceBranchMoveTabuMaker.cs	(revision 7832)
@@ -0,0 +1,72 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization.Operators;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("ReplaceBranchMoveTabuMaker", "")]
+  [StorableClass]
+  public class ReplaceBranchMoveTabuMaker : TabuMaker, ISymbolicExpressionTreeMoveOperator {
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+    public ILookupParameter<ReplaceBranchMove> ReplaceBranchMoveParameter {
+      get { return (LookupParameter<ReplaceBranchMove>)Parameters["ReplaceBranchMove"]; }
+    }
+
+    [StorableConstructor]
+    protected ReplaceBranchMoveTabuMaker(bool deserializing) : base(deserializing) { }
+    protected ReplaceBranchMoveTabuMaker(ReplaceBranchMoveTabuMaker original, Cloner cloner) : base(original, cloner) { }
+    public ReplaceBranchMoveTabuMaker()
+      : base() {
+      Parameters.Add(new LookupParameter<ReplaceBranchMove>("ReplaceBranchMove", "The move that was made."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The solution as symbolic expression tree."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ReplaceBranchMoveTabuMaker(this, cloner);
+    }
+
+    protected override IItem GetTabuAttribute(bool maximization, double quality, double moveQuality) {
+      var move = ReplaceBranchMoveParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      double baseQuality = moveQuality;
+      if (maximization && quality > moveQuality || !maximization && quality < moveQuality) baseQuality = quality; // we make an uphill move, the lower bound is the solution quality
+
+      List<int> path = new List<int>();
+      path.Add(move.SubtreeIndex);
+      var parent = move.Parent.Parent;
+      var child = move.Parent;
+      while (parent != null) {
+        path.Add(parent.IndexOfSubtree(child));
+        child = parent;
+        parent = parent.Parent;
+      }
+      path.Reverse();
+      return new ChangeNodeTypeMoveAbsoluteAttribute(path.ToArray(), baseQuality);
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMoveGenerator.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMoveGenerator.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMoveGenerator.cs	(revision 7832)
@@ -30,7 +30,7 @@
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  [Item("ShakeMoveGenerator", "Operator that generates moves for shaking a single symbolic expression tree node.")]
+  [Item("ShakeExhaustiveMoveGenerator", "Operator that generates moves for shaking a single symbolic expression tree node.")]
   [StorableClass]
-  public class ShakeMoveGenerator : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, IMoveGenerator, IStochasticOperator {
+  public class ShakeMoveGenerator : SingleSuccessorOperator, ISymbolicExpressionTreeMoveOperator, IExhaustiveMoveGenerator, IStochasticOperator {
     public override bool CanChangeName {
       get { return false; }
@@ -39,6 +39,6 @@
       get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
     }
-    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
     }
     public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
@@ -55,5 +55,5 @@
       : base() {
       Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
-      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
       Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The moves that should be generated in subscopes."));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
@@ -66,5 +66,5 @@
 
     public override IOperation Apply() {
-      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
       var moves = GenerateMoves(tree);
       string moveParameterName = ChangeNodeTypeMoveParameter.ActualName;
@@ -81,6 +81,5 @@
     }
 
-    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(SymbolicExpressionTree tree) {
-      var g = tree.Root.Grammar;
+    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(ISymbolicExpressionTree tree) {
       return (from parent in tree.Root.GetSubtree(0).IterateNodesPrefix()
               from i in Enumerable.Range(0, parent.SubtreeCount)
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMultiMoveGenerator.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMultiMoveGenerator.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/ShakeMultiMoveGenerator.cs	(revision 7832)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -46,6 +45,6 @@
       set { SampleSizeParameter.Value = value; }
     }
-    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
-      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
     }
     public ILookupParameter<ChangeNodeTypeMove> ChangeNodeTypeMoveParameter {
@@ -64,5 +63,5 @@
       Parameters.Add(new ValueLookupParameter<IntValue>("SampleSize", "The number of moves to generate."));
 
-      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree", "The symbolic expression tree for which moves should be generated."));
       Parameters.Add(new LookupParameter<ChangeNodeTypeMove>("ChangeNodeTypeMove", "The moves that should be generated in subscopes."));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope where the moves should be added as subscopes."));
@@ -75,16 +74,12 @@
 
     public override IOperation Apply() {
-      SymbolicExpressionTree tree = SymbolicExpressionTreeParameter.ActualValue;
-      var moves = ChangeNodeTypeMoveGenerator.GenerateMoves(tree).ToArray();
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var random = RandomParameter.ActualValue;
+      int n = SampleSizeParameter.ActualValue.Value;
+      var moves = ChangeNodeTypeMultiMoveGenerator.GenerateMoves(tree, random, n);
       string moveParameterName = ChangeNodeTypeMoveParameter.ActualName;
       var moveScopes = new List<Scope>();
-      var random = RandomParameter.ActualValue;
-      int n = SampleSizeParameter.ActualValue.Value;
 
-      var rand = Enumerable.Range(0, moves.Length).Select(i => random.NextDouble()).ToArray();
-      Array.Sort(rand, moves);
-      n = Math.Min(n, moves.Length);
-
-      foreach (var m in moves.Take(n)) {
+      foreach (var m in moves) {
         m.NewChild.ShakeLocalParameters(random, 1);
         var moveScope = new Scope(moveScopes.Count.ToString());
@@ -95,4 +90,20 @@
       return base.Apply();
     }
+
+    public static IEnumerable<ChangeNodeTypeMove> GenerateMoves(ISymbolicExpressionTree tree, IRandom random, int n) {
+      int count = 0;
+      var g = tree.Root.Grammar;
+      var possibleChildren = (from parent in tree.Root.GetSubtree(0).IterateNodesPrefix()
+                              from i in Enumerable.Range(0, parent.SubtreeCount)
+                              let currentChild = parent.GetSubtree(i)
+                              where currentChild.HasLocalParameters
+                              select new { parent, i, currentChild }).ToArray();
+      if (possibleChildren.Length < n) n = possibleChildren.Length;
+      while (count < n) {
+        var selected = possibleChildren[random.Next(possibleChildren.Length)];
+        yield return new ChangeNodeTypeMove(tree, selected.parent, selected.i, (ISymbolicExpressionTreeNode)selected.currentChild.Clone());
+        count++;
+      }
+    }
   }
 }
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/SymbolicExpressionTreeMoveAttribute.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/SymbolicExpressionTreeMoveAttribute.cs	(revision 7832)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Moves/SymbolicExpressionTreeMoveAttribute.cs	(revision 7832)
@@ -0,0 +1,49 @@
+﻿#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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+  [Item("SymbolicExpressionTreeMoveAttribute", "Base class for specifying a move attribute for symbolic expression trees")]
+  [StorableClass]
+  public class SymbolicExpressionTreeMoveAttribute : Item {
+    [Storable]
+    public double MoveQuality { get; protected set; }
+
+    [StorableConstructor]
+    protected SymbolicExpressionTreeMoveAttribute(bool deserializing) : base(deserializing) { }
+    protected SymbolicExpressionTreeMoveAttribute(SymbolicExpressionTreeMoveAttribute original, Cloner cloner)
+      : base(original, cloner) {
+      this.MoveQuality = original.MoveQuality;
+    }
+    public SymbolicExpressionTreeMoveAttribute() : this(0) { }
+    public SymbolicExpressionTreeMoveAttribute(double moveQuality)
+      : base() {
+      MoveQuality = moveQuality;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicExpressionTreeMoveAttribute(this, cloner);
+    }
+  }
+}
Index: branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs
===================================================================
--- branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 7802)
+++ branches/GP-MoveOperators/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeNode.cs	(revision 7832)
@@ -53,5 +53,5 @@
     protected SymbolicExpressionTreeNode(bool deserializing) { }
     protected SymbolicExpressionTreeNode(SymbolicExpressionTreeNode original, Cloner cloner)
-      : base() {
+      : base(original, cloner) {
       symbol = original.symbol; // symbols are reused
       length = original.length;
