Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/MultiSymbolicExpressionTreeArchitectureManipulator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/RandomArchitectureAlteringOperator.cs	(revision 3462)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/ArchitectureAlteringOperators/MultiSymbolicExpressionTreeArchitectureManipulator.cs	(revision 3534)
@@ -22,51 +22,114 @@
 using System;
 using System.Linq;
-using HeuristicLab.Common;
+using HeuristicLab.Collections;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
-using System.Collections.Generic;
-using System.Text;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.ArchitectureAlteringOperators {
-  /// <summary>
-  /// Manipulates a symbolic expression by applying one architecture altering operator randomly.
-  /// </summary>
-  [Item("RandomArchitectureAlteringOperator", "Manipulates a symbolic expression by applying one architecture altering operator randomly.")]
+  [Item("MultiSymbolicExpressionTreeArchitectureManipulator", "Randomly selects and applies one of its architecture manipulators every time it is called.")]
   [StorableClass]
-  public class RandomArchitectureAlteringOperator : SymbolicExpressionTreeArchitectureAlteringOperator {
-    #region Parameter Properties
-    public IValueParameter<ItemList<SymbolicExpressionTreeArchitectureAlteringOperator>> OperatorsParameter {
-      get { return (IValueParameter<ItemList<SymbolicExpressionTreeArchitectureAlteringOperator>>)Parameters["Operators"]; }
+  public class MultiSymbolicExpressionTreeArchitectureManipulator : StochasticMultiOperator<ISymbolicExpressionTreeArchitectureManipulator>, ISymbolicExpressionTreeArchitectureManipulator, IStochasticOperator {
+    private const string MaxTreeSizeParameterName = "MaxTreeSize";
+    private const string MaxTreeHeightParameterName = "MaxTreeHeight";
+    private const string SymbolicExpressionGrammarParameterName = "SymbolicExpressionGrammar";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string MaxFunctionArgumentsParameterName = "MaxFunctionArguments";
+    private const string MaxFunctionDefiningBranchesParameterName = "MaxFunctionDefiningBranches";
+
+    public override bool CanChangeName {
+      get { return false; }
     }
-    #endregion
-    #region Properties
-    public ItemList<SymbolicExpressionTreeArchitectureAlteringOperator> Operators {
-      get { return OperatorsParameter.Value; }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+    #region ISymbolicExpressionTreeArchitectureManipulator Members
+    public IValueLookupParameter<IntValue> MaxFunctionDefinitionsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MaxFunctionDefiningBranchesParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> MaxFunctionArgumentsParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[MaxFunctionArgumentsParameterName]; }
     }
     #endregion
 
-    public RandomArchitectureAlteringOperator()
+
+    #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 MultiSymbolicExpressionTreeArchitectureManipulator(bool deserializing) : base(deserializing) { }
+    public MultiSymbolicExpressionTreeArchitectureManipulator()
       : base() {
-      var operators = new ItemList<SymbolicExpressionTreeArchitectureAlteringOperator>();
-      operators.Add(new ArgumentCreater());
-      operators.Add(new ArgumentDeleter());
-      operators.Add(new ArgumentDuplicater());
-      operators.Add(new SubroutineCreater());
-      operators.Add(new SubroutineDeleter());
-      operators.Add(new SubroutineDuplicater());
-      Parameters.Add(new ValueParameter<ItemList<SymbolicExpressionTreeArchitectureAlteringOperator>>("Operators",
-        "The list of architecture altering operators from which a random operator should be called.",
-        operators));
+      Parameters.Add(new LookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression tree on which the operator should be applied."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MaxFunctionDefiningBranchesParameterName, "The maximal allowed number of function defining branches."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(MaxFunctionArgumentsParameterName, "The maximal allowed number of arguments of a newly created function."));
+      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 ArgumentCreater());
+      Operators.Add(new ArgumentDeleter());
+      Operators.Add(new ArgumentDuplicater());
+      Operators.Add(new SubroutineCreater());
+      Operators.Add(new SubroutineDeleter());
+      Operators.Add(new SubroutineDuplicater());
     }
 
-    public override void ModifyArchitecture(IRandom random, SymbolicExpressionTree tree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, IntValue maxFunctionDefiningBranches, IntValue maxFunctionArguments, out bool success) {
-      var selectedOperator = Operators.SelectRandom(random);
-      selectedOperator.ModifyArchitecture(random, tree, grammar, maxTreeSize, maxTreeHeight, maxFunctionDefiningBranches, maxFunctionArguments, out success);
+    protected override void Operators_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<ISymbolicExpressionTreeArchitectureManipulator>> e) {
+      base.Operators_ItemsReplaced(sender, e);
+      ParameterizeManipulators();
     }
+
+    protected override void Operators_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<ISymbolicExpressionTreeArchitectureManipulator>> e) {
+      base.Operators_ItemsAdded(sender, e);
+      ParameterizeManipulators();
+    }
+
+    private void ParameterizeManipulators() {
+      foreach (ISymbolicExpressionTreeArchitectureManipulator manipulator in Operators.OfType<ISymbolicExpressionTreeArchitectureManipulator>()) {
+        manipulator.MaxTreeSizeParameter.ActualName = MaxTreeSizeParameter.Name;
+        manipulator.MaxTreeHeightParameter.ActualName = MaxTreeHeightParameter.Name;
+        manipulator.SymbolicExpressionGrammarParameter.ActualName = SymbolicExpressionGrammarParameter.Name;
+        manipulator.SymbolicExpressionTreeParameter.ActualName = SymbolicExpressionTreeParameter.Name;
+        manipulator.MaxFunctionDefinitionsParameter.ActualName = MaxFunctionArgumentsParameter.Name;
+        manipulator.MaxFunctionArgumentsParameter.ActualName = MaxFunctionArgumentsParameter.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 architecture manipulator to choose from.");
+      return base.Apply();
+    }
+
+    #region ISymbolicExpressionTreeArchitectureManipulator Members
+    public void ModifyArchitecture(IRandom random, SymbolicExpressionTree symbolicExpressionTree, ISymbolicExpressionGrammar grammar, IntValue maxTreeSize, IntValue maxTreeHeight, IntValue maxFunctionDefiningBranches, IntValue maxFunctionArguments, out bool success) {
+      var op = Operators.SelectRandom(random);
+      op.ModifyArchitecture(random, symbolicExpressionTree, grammar, maxTreeSize, maxTreeHeight, maxFunctionDefiningBranches, maxFunctionArguments, out success);
+    }
+    #endregion
   }
 }
