Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/MultiSymbolicExpressionTreeManipulator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/MultiSymbolicExpressionTreeManipulator.cs	(revision 3534)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/MultiSymbolicExpressionTreeManipulator.cs	(revision 3534)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators {
+  [Item("MultiSymbolicExpressionTreeManipulator", "Randomly selects and applies one of its manipulators every time it is called.")]
+  [StorableClass]
+  public class MultiSymbolicExpressionTreeManipulator : StochasticMultiOperator<ISymbolicExpressionTreeManipulator>, ISymbolicExpressionTreeManipulator, IStochasticOperator {
+    private const string MaxTreeSizeParameterName = "MaxTreeSize";
+    private const string MaxTreeHeightParameterName = "MaxTreeHeight";
+    private const string SymbolicExpressionGrammarParameterName = "SymbolicExpressionGrammar";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    #region ISymbolicExpressionTreeManipulator Members
+    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    #endregion
+
+    #region ISymbolicExpressionTreeOperator Members
+    public IValueLookupParameter<IntValue> MaxTreeSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MaxTreeSizeParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> MaxTreeHeightParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MaxTreeHeightParameterName]; }
+    }
+    public ILookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionGrammarParameter {
+      get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters[SymbolicExpressionGrammarParameterName]; }
+    }
+    #endregion
+
+
+    [StorableConstructor]
+    private MultiSymbolicExpressionTreeManipulator(bool deserializing) : base(deserializing) { }
+    public MultiSymbolicExpressionTreeManipulator()
+      : base() {
+      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MaxTreeSizeParameterName, "The maximal size (number of nodes) of the symbolic expression tree."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MaxTreeHeightParameterName, "The maximal height of the symbolic expression tree (a tree with one node has height = 0)."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>(SymbolicExpressionGrammarParameterName, "The grammar that defines the allowed symbols and syntax of the symbolic expression trees."));
+
+      Operators.Add(new FullTreeShaker());
+      Operators.Add(new OnePointShaker());
+      Operators.Add(new ChangeNodeTypeManipulation());
+    }
+
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ISymbolicExpressionTreeManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeManipulators();
+    }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<ISymbolicExpressionTreeManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeManipulators();
+    }
+
+    private void ParameterizeManipulators() {
+      foreach (ISymbolicExpressionTreeManipulator manipulator in Operators.OfType<ISymbolicExpressionTreeManipulator>()) {
+        manipulator.MaxTreeSizeParameter.ActualName = MaxTreeSizeParameter.Name;
+        manipulator.MaxTreeHeightParameter.ActualName = MaxTreeHeightParameter.Name;
+        manipulator.SymbolicExpressionGrammarParameter.ActualName = SymbolicExpressionGrammarParameter.Name;
+        manipulator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
+      }
+
+      foreach (IStochasticOperator manipulator in Operators.OfType<IStochasticOperator>()) {
+        manipulator.RandomParameter.ActualName = RandomParameter.Name;
+      }
+    }
+
+    public override IOperation Apply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one symbolic expression tree manipulator to choose from.");
+      return base.Apply();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/SymbolicExpressionTreeManipulator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/SymbolicExpressionTreeManipulator.cs	(revision 3512)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Manipulators/SymbolicExpressionTreeManipulator.cs	(revision 3534)
@@ -27,4 +27,5 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Manipulators {
@@ -34,10 +35,14 @@
   [Item("SymbolicExpressionTreeManipulator", "A base class for operators that manipulate symbolic expression trees.")]
   [StorableClass]
-  public abstract class SymbolicExpressionTreeManipulator : SymbolicExpressionTreeOperator, IManipulator {
+  public abstract class SymbolicExpressionTreeManipulator : SymbolicExpressionTreeOperator, ISymbolicExpressionTreeManipulator {
     private const string FailedManipulationEventsParameterName = "FailedManipulationEvents";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
 
     #region Parameter Properties
     public IValueParameter<IntValue> FailedManipulationEventsParameter {
       get { return (IValueParameter<IntValue>)Parameters[FailedManipulationEventsParameterName]; }
+    }
+    public ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
     }
     #endregion
@@ -47,4 +52,7 @@
       get { return FailedManipulationEventsParameter.Value; }
     }
+    public SymbolicExpressionTree SymbolicExpressionTree {
+      get { return SymbolicExpressionTreeParameter.ActualValue; }
+    }
     #endregion
 
@@ -52,4 +60,5 @@
       : base() {
       Parameters.Add(new ValueParameter<IntValue>(FailedManipulationEventsParameterName, "The number of failed manipulation events.", new IntValue()));
+      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
     }
 
