Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Creators/ProbabilisticTreeCreator.cs	(revision 3237)
@@ -51,11 +51,12 @@
       do {
         try {
-          // determine possible root symbols to create a tree of the target size
-          var possibleRootSymbols = from symbol in grammar.AllowedSymbols(grammar.StartSymbol, 0)
-                                    where treeSize <= grammar.MaximalExpressionLength(symbol)
-                                    where treeSize >= grammar.MinimalExpressionLength(symbol)
-                                    select symbol;
-          Symbol rootSymbol = SelectRandomSymbol(random, possibleRootSymbols);
-          tree.Root = PTC2(random, grammar, rootSymbol, treeSize, maxTreeHeight);
+          tree.Root = PTC2(random, grammar, grammar.StartSymbol, treeSize+1, maxTreeHeight+1);
+          //// determine possible root symbols to create a tree of the target size
+          //var possibleRootSymbols = from symbol in grammar.AllowedSymbols(grammar.StartSymbol, 0)
+          //                          where treeSize <= grammar.MaximalExpressionLength(symbol)
+          //                          where treeSize >= grammar.MinimalExpressionLength(symbol)
+          //                          select symbol;
+          //Symbol rootSymbol = SelectRandomSymbol(random, possibleRootSymbols);
+          //tree.Root = PTC2(random, grammar, rootSymbol, treeSize, maxTreeHeight);
         }
         catch (ArgumentException) {
@@ -149,13 +150,13 @@
       int minArity = grammar.MinSubTrees(symbol);
       int maxArity = grammar.MaxSubTrees(symbol);
-      if (maxArity >= targetSize) {
+      if (maxArity > targetSize) {
         maxArity = targetSize;
       }
       // the min number of sub-trees has to be set to a value that is large enough so that the largest possible tree is at least tree size
       // if 1..3 trees are possible and the largest possible first sub-tree is smaller larger than the target size then minArity should be at least 2
-      int aggregatedLongestExpressionLength = 1;
+      long aggregatedLongestExpressionLength = 0;
       for (int i = 0; i < maxArity; i++) {
         aggregatedLongestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
-                                              select grammar.MaximalExpressionLength(symbol)).Max();
+                                              select grammar.MaximalExpressionLength(s)).Max();
         if (aggregatedLongestExpressionLength < targetSize) minArity = i;
         else break;
@@ -164,8 +165,8 @@
       // the max number of sub-trees has to be set to a value that is small enough so that the smallest possible tree is at most tree size 
       // if 1..3 trees are possible and the smallest possible first sub-tree is already larger than the target size then maxArity should be at most 0
-      int aggregatedShortestExpressionLength = 1;
+      long aggregatedShortestExpressionLength = 0;
       for (int i = 0; i < maxArity; i++) {
         aggregatedShortestExpressionLength += (from s in grammar.AllowedSymbols(symbol, i)
-                                               select grammar.MinimalExpressionLength(symbol)).Min();
+                                               select grammar.MinimalExpressionLength(s)).Min();
         if (aggregatedShortestExpressionLength > targetSize) {
           maxArity = i;
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/GPCrossoverBase.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/GPCrossoverBase.cs	(revision 3236)
+++ 	(revision )
@@ -1,58 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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 HeuristicLab.Core;
-using System.Diagnostics;
-
-namespace HeuristicLab.Encodings.SymbolicExpressionTree {
-  public abstract class GPCrossoverBase : CrossoverBase {
-    public GPCrossoverBase()
-      : base() {
-      AddVariableInfo(new VariableInfo("FunctionLibrary", "The operator library containing all available operators", typeof(FunctionLibrary), VariableKind.In));
-      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to crossover", typeof(IGeneticProgrammingModel), VariableKind.In | VariableKind.New));
-    }
-
-    internal abstract IFunctionTree Cross(IScope scope, TreeGardener gardener, IRandom random, IFunctionTree tree0, IFunctionTree tree1);
-
-    protected override void Cross(IScope scope, IRandom random) {
-      FunctionLibrary opLibrary = GetVariableValue<FunctionLibrary>("FunctionLibrary", scope, true);
-      TreeGardener gardener = new TreeGardener(random, opLibrary);
-
-      if (scope.SubScopes.Count != 2)
-        throw new InvalidOperationException("Number of parents must be exactly two.");
-
-      IGeneticProgrammingModel parent0 = GetVariableValue<IGeneticProgrammingModel>("FunctionTree", scope.SubScopes[0], false);
-      IGeneticProgrammingModel parent1 = GetVariableValue<IGeneticProgrammingModel>("FunctionTree", scope.SubScopes[1], false);
-
-      // randomly swap parents to remove a possible bias from selection (e.g. when using gender-specific selection)
-      if (random.NextDouble() < 0.5) {
-        IGeneticProgrammingModel tmp = parent0;
-        parent0 = parent1;
-        parent1 = tmp;
-      }
-
-      IFunctionTree child = Cross(scope, gardener, random, parent0.FunctionTree, parent1.FunctionTree);
-      Debug.Assert(gardener.IsValidTree(child));
-      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), new GeneticProgrammingModel(child)));
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/StandardCrossOver.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/StandardCrossOver.cs	(revision 3236)
+++ 	(revision )
@@ -1,78 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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.Core;
-using HeuristicLab.GP.Interfaces;
-
-namespace HeuristicLab.Encodings.SymbolicExpressionTree {
-  public class StandardCrossOver : SizeConstrictedGPCrossoverBase {
-    private int MaxRecombinationTries { get { return 20; } }
-
-    public override string Description {
-      get {
-        return @"Takes two parent individuals P0 and P1 each. Selects a random node N0 of P0 and a random node N1 of P1.
-And replaces the branch with root0 N0 in P0 with N1 from P1 if the tree-size limits are not violated.
-When recombination with N0 and N1 would create a tree that is too large or invalid the operator randomly selects new N0 and N1 
-until a valid configuration is found.";
-      }
-    }
-
-    internal override IFunctionTree Cross(TreeGardener gardener, IRandom random, IFunctionTree tree0, IFunctionTree tree1, int maxTreeSize, int maxTreeHeight) {
-      int tries = 0;
-      List<IFunctionTree> allowedCrossoverPoints = null;
-      IFunctionTree parent0;
-      int replacedChildIndex;
-      do {
-        // select a random crossover point in the first parent tree0
-        parent0 = null;
-        while (parent0 == null) parent0 = gardener.GetRandomParentNode(tree0);
-        // select a random branch to replace
-        replacedChildIndex = random.Next(parent0.SubTrees.Count);
-
-        // calculate the max size and height that the inserted branch can have 
-        int maxInsertedBranchSize = maxTreeSize - (tree0.GetSize() - parent0.SubTrees[replacedChildIndex].GetSize());
-        int maxInsertedBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, parent0); // branchlevel is 1 if tree0==parent0
-
-        IList<IFunction> allowedFunctions = new List<IFunction>(gardener.GetAllowedSubFunctions(parent0.Function, replacedChildIndex));
-        allowedCrossoverPoints = GetPossibleCrossoverPoints(tree1, maxInsertedBranchSize, maxInsertedBranchHeight, allowedFunctions);
-      } while (allowedCrossoverPoints.Count == 0 && tries++ < MaxRecombinationTries);
-
-      if (allowedCrossoverPoints.Count > 0) {
-        IFunctionTree branch1 = allowedCrossoverPoints[random.Next(allowedCrossoverPoints.Count)];
-
-        // replace the branch in tree0 with the selected branch from tree1
-        parent0.RemoveSubTree(replacedChildIndex);
-        parent0.InsertSubTree(replacedChildIndex, branch1);
-      }
-      return tree0;
-    }
-
-    private List<IFunctionTree> GetPossibleCrossoverPoints(IFunctionTree tree, int maxInsertedBranchSize, int maxInsertedBranchHeight, IList<IFunction> allowedFunctions) {
-      List<IFunctionTree> crossoverPoints = new List<IFunctionTree>();
-      foreach (IFunctionTree possiblePoint in TreeGardener.GetAllSubTrees(tree)) {
-        if (allowedFunctions.Contains(possiblePoint.Function) && possiblePoint.GetSize() <= maxInsertedBranchSize && possiblePoint.GetHeight() <= maxInsertedBranchHeight)
-          crossoverPoints.Add(possiblePoint);
-      }
-      return crossoverPoints;
-    }
-  }
-}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs	(revision 3237)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Crossovers/SubtreeCrossover.cs	(revision 3237)
@@ -0,0 +1,156 @@
+#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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
+using System.Linq;
+using System;
+using HeuristicLab.Parameters;
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
+
+
+  /// <summary>
+  /// Takes two parent individuals P0 and P1 each. Selects a random node N0 of P0 and a random node N1 of P1.
+  /// And replaces the branch with root0 N0 in P0 with N1 from P1 if the tree-size limits are not violated.
+  /// When recombination with N0 and N1 would create a tree that is too large or invalid the operator randomly selects new N0 and N1 
+  /// until a valid configuration is found.
+  /// </summary>  
+  [Item("SubtreeCrossover", "An operator which performs subtree swapping crossover.")]
+  [StorableClass]
+  public class SubtreeCrossover : SymbolicExpressionTreeCrossover {
+    private const int MAX_TRIES = 100;
+
+    public IValueLookupParameter<PercentValue> InternalCrossoverPointProbabilityParameter {
+      get { return (IValueLookupParameter<PercentValue>)Parameters["InternalCrossoverPointProbability"]; }
+    }
+
+    public SubtreeCrossover()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<PercentValue>("InternalCrossoverPointProbability", "The probability to select an internal crossover point (instead of a leaf node).", new PercentValue(0.9)));
+    }
+
+    protected override SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
+      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
+      IntValue maxTreeSize, IntValue maxTreeHeight) {
+      return Apply(random, grammar, parent0, parent1, InternalCrossoverPointProbabilityParameter.ActualValue.Value, maxTreeSize.Value, maxTreeHeight.Value);
+    }
+
+    public static SymbolicExpressionTree Apply(IRandom random, ISymbolicExpressionGrammar grammar,
+      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
+      double internalCrossoverPointProbability, int maxTreeSize, int maxTreeHeight) {
+      int tries = 0;
+      while (tries++ < MAX_TRIES) {
+        // select a random crossover point in the first parent 
+        SymbolicExpressionTreeNode crossoverPoint0;
+        int replacedSubtreeIndex;
+        SelectCrossoverPoint(random, parent0, internalCrossoverPointProbability, out crossoverPoint0, out replacedSubtreeIndex);
+
+        // calculate the max size and height that the inserted branch can have 
+        int maxInsertedBranchSize = maxTreeSize - (parent0.Size - crossoverPoint0.SubTrees[replacedSubtreeIndex].GetSize());
+        int maxInsertedBranchHeight = maxTreeHeight - GetBranchLevel(parent0.Root, crossoverPoint0);
+
+        var allowedBranches = from branch in IterateNodes(parent1.Root)
+                              where branch.GetSize() < maxInsertedBranchSize
+                              where branch.GetHeight() < maxInsertedBranchHeight
+                              where grammar.AllowedSymbols(crossoverPoint0.Symbol, replacedSubtreeIndex).Contains(branch.Symbol)
+                              select branch;
+
+        if (allowedBranches.Count() > 0) {
+          var selectedBranch = SelectRandomBranch(random, allowedBranches, internalCrossoverPointProbability);
+
+          // manipulate the tree of parent0 in place
+          // replace the branch in tree0 with the selected branch from tree1
+          crossoverPoint0.RemoveSubTree(replacedSubtreeIndex);
+          crossoverPoint0.InsertSubTree(replacedSubtreeIndex, selectedBranch);
+          return parent0;
+        }
+      }
+
+      // TODO: we should have a way to track the number of failed crossover attempts
+      // for now just return the first parent unchanged
+      return parent0;
+    }
+
+    private static void SelectCrossoverPoint(IRandom random, SymbolicExpressionTree parent0, double internalNodeProbability, out SymbolicExpressionTreeNode crossoverPoint, out int subtreeIndex) {
+      var crossoverPoints = from branch in IterateNodes(parent0.Root)
+                            where branch.SubTrees.Count > 0
+                            from index in Enumerable.Range(0, branch.SubTrees.Count)
+                            let p = new { CrossoverPoint = branch, SubtreeIndex = index, IsLeaf = branch.SubTrees[index].SubTrees.Count == 0 }
+                            select p;
+      var internalCrossoverPoints = (from p in crossoverPoints
+                                     where !p.IsLeaf
+                                     select p).ToList();
+      // select internal crossover point or leaf
+      if (random.NextDouble() < internalNodeProbability && internalCrossoverPoints.Count > 0) {
+        var selectedCrossoverPoint = internalCrossoverPoints[random.Next(internalCrossoverPoints.Count)];
+        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
+        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+      } else {
+        var leafCrossoverPoints = (from p in crossoverPoints
+                                   where p.IsLeaf
+                                   select p).ToList();
+        var selectedCrossoverPoint = leafCrossoverPoints[random.Next(leafCrossoverPoints.Count)];
+        crossoverPoint = selectedCrossoverPoint.CrossoverPoint;
+        subtreeIndex = selectedCrossoverPoint.SubtreeIndex;
+      }
+    }
+
+    private static SymbolicExpressionTreeNode SelectRandomBranch(IRandom random, IEnumerable<SymbolicExpressionTreeNode> branches, double internalNodeProbability) {
+      if (internalNodeProbability < 0.0 || internalNodeProbability > 1.0) throw new ArgumentException("internalNodeProbability");
+      var groupedBranches = from branch in branches
+                            group branch by branch.SubTrees.Count into g
+                            select g;
+      var allowedInternalBranches = (from g in groupedBranches
+                                     where g.Key > 0
+                                     from branch in g
+                                     select branch).ToList();
+      if (random.NextDouble() < internalNodeProbability && allowedInternalBranches.Count > 0) {
+        return allowedInternalBranches[random.Next(allowedInternalBranches.Count)];
+      } else {
+        var allowedLeafBranches = (from g in groupedBranches
+                                   where g.Key == 0
+                                   from leaf in g
+                                   select leaf).ToList();
+        return allowedLeafBranches[random.Next(allowedLeafBranches.Count)];
+      }
+    }
+
+    private static IEnumerable<SymbolicExpressionTreeNode> IterateNodes(SymbolicExpressionTreeNode root) {
+      foreach (var subTree in root.SubTrees) {
+        foreach (var branch in IterateNodes(subTree)) {
+          yield return branch;
+        }
+      }
+      yield return root;
+    }
+
+    private static int GetBranchLevel(SymbolicExpressionTreeNode root, SymbolicExpressionTreeNode point) {
+      if (root == point) return 0;
+      foreach (var subtree in root.SubTrees) {
+        int branchLevel = GetBranchLevel(subtree, point);
+        if (branchLevel < int.MaxValue) return 1 + branchLevel;
+      }
+      return int.MaxValue;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3.csproj	(revision 3237)
@@ -24,4 +24,5 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
+    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -70,4 +71,6 @@
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml.Linq">
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
@@ -80,4 +83,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Crossovers\SubtreeCrossover.cs" />
     <Compile Include="Interfaces\ISymbolicExpressionGrammar.cs" />
     <Compile Include="Creators\ProbabilisticTreeCreator.cs" />
@@ -88,5 +92,12 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="Symbol.cs" />
+    <Compile Include="SymbolicExpressionTreeCrossover.cs" />
     <Compile Include="SymbolicExpressionTreeNode.cs" />
+    <Compile Include="Views\SymbolicExpressionTreeView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Views\SymbolicExpressionTreeView.Designer.cs">
+      <DependentUpon>SymbolicExpressionTreeView.cs</DependentUpon>
+    </Compile>
   </ItemGroup>
   <ItemGroup>
@@ -100,4 +111,8 @@
       <Name>HeuristicLab.Collections-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
+      <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
+      <Name>HeuristicLab.Core.Views-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
       <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
@@ -107,4 +122,12 @@
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
       <Name>HeuristicLab.Data-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.2\HeuristicLab.MainForm.WindowsForms-3.2.csproj">
+      <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
+      <Name>HeuristicLab.MainForm.WindowsForms-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm\3.2\HeuristicLab.MainForm-3.2.csproj">
+      <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
+      <Name>HeuristicLab.MainForm-3.2</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
@@ -134,5 +157,9 @@
   </ItemGroup>
   <ItemGroup>
-    <Folder Include="Crossovers\" />
+    <EmbeddedResource Include="Views\SymbolicExpressionTreeView.resx">
+      <DependentUpon>SymbolicExpressionTreeView.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
     <Folder Include="Manipulators\" />
   </ItemGroup>
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Interfaces/ISymbolicExpressionGrammar.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Interfaces/ISymbolicExpressionGrammar.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Interfaces/ISymbolicExpressionGrammar.cs	(revision 3237)
@@ -42,4 +42,6 @@
     int MinSubTrees(Symbol start);
     int MaxSubTrees(Symbol start);
+
+    bool IsValidExpression(SymbolicExpressionTree expression);
   }
 }
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionGrammar.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionGrammar.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionGrammar.cs	(revision 3237)
@@ -81,5 +81,5 @@
       get { return startSymbol; }
     }
-   
+
     public IEnumerable<Symbol> AllowedSymbols(Symbol parent, int argumentIndex) {
       return allowedSymbols[parent][argumentIndex];
@@ -106,4 +106,8 @@
     }
 
+    public bool IsValidExpression(SymbolicExpressionTree expression) {
+      throw new NotImplementedException();
+    }
+
     #endregion
   }
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTree.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTree.cs	(revision 3237)
@@ -26,4 +26,5 @@
 using System.Xml;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCrossover.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCrossover.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeCrossover.cs	(revision 3237)
@@ -26,12 +26,14 @@
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System;
+using System.Diagnostics;
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
   /// <summary>
-  /// A base class for operators that perform a crossover of real-valued vectors.
+  /// A base class for operators that perform a crossover of symbolic expression trees.
   /// </summary>
-  [Item("RealVectorCrossover", "A base class for operators that perform a crossover of real-valued vectors.")]
+  [Item("SymbolicExpressionTreeCrossover", "A base class for operators that perform a crossover of symbolic expression trees.")]
   [StorableClass]
-  public abstract class RealVectorCrossover : SingleSuccessorOperator, IRealVectorCrossover, IStochasticOperator {
+  public abstract class SymbolicExpressionTreeCrossover : SingleSuccessorOperator, ICrossover, IStochasticOperator {
     public override bool CanChangeName {
       get { return false; }
@@ -41,31 +43,59 @@
       get { return (LookupParameter<IRandom>)Parameters["Random"]; }
     }
-    public ILookupParameter<ItemArray<RealVector>> ParentsParameter {
-      get { return (SubScopesLookupParameter<RealVector>)Parameters["Parents"]; }
+    public ILookupParameter<ItemArray<SymbolicExpressionTree>> ParentsParameter {
+      get { return (SubScopesLookupParameter<SymbolicExpressionTree>)Parameters["Parents"]; }
     }
-    public ILookupParameter<RealVector> ChildParameter {
-      get { return (ILookupParameter<RealVector>)Parameters["Child"]; }
+    public ILookupParameter<SymbolicExpressionTree> ChildParameter {
+      get { return (ILookupParameter<SymbolicExpressionTree>)Parameters["Child"]; }
     }
-    public IValueLookupParameter<DoubleMatrix> BoundsParameter {
-      get { return (IValueLookupParameter<DoubleMatrix>)Parameters["Bounds"]; }
+    public IValueLookupParameter<IntValue> MaxTreeSizeParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaxTreeSize"]; }
+    }
+    public IValueLookupParameter<IntValue> MaxTreeHeightParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["MaxTreeHeight"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionGrammar> SymbolicExpressionGrammarParameter {
+      get { return (ILookupParameter<ISymbolicExpressionGrammar>)Parameters["SymbolicExpressionGrammar"]; }
     }
 
-    protected RealVectorCrossover()
+    protected SymbolicExpressionTreeCrossover()
       : base() {
       Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used for stochastic crossover operators."));
-      Parameters.Add(new SubScopesLookupParameter<RealVector>("Parents", "The parent vectors which should be crossed."));
-      Parameters.Add(new LookupParameter<RealVector>("Child", "The child vector resulting from the crossover."));
-      Parameters.Add(new ValueLookupParameter<DoubleMatrix>("Bounds", "The lower and upper bounds of the real vector."));
+      Parameters.Add(new SubScopesLookupParameter<SymbolicExpressionTree>("Parents", "The parent symbolic expression trees which should be crossed."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaxTreeSize", "The maximal size (number of nodes) of the symbolic expression tree that should be initialized."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("MaxTreeHeight", "The maximal height of the symbolic expression tree that should be initialized (a tree with one node has height = 0)."));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionGrammar>("SymbolicExpressionGrammar", "The grammar that defines the allowed symbols and syntax of the symbolic expression trees."));
+      Parameters.Add(new LookupParameter<SymbolicExpressionTree>("Child", "The child symbolic expression tree resulting from the crossover."));
     }
 
     public sealed override IOperation Apply() {
-      RealVector result = Cross(RandomParameter.ActualValue, ParentsParameter.ActualValue);
-      DoubleMatrix bounds = BoundsParameter.ActualValue;
-      if (bounds != null) BoundsChecker.Apply(result, bounds);
+      if (ParentsParameter.ActualValue.Length != 2)
+        throw new ArgumentException("Number of parents must be exactly two for symbolic expression tree crossover operators.");
+
+      SymbolicExpressionTree parent0 = ParentsParameter.ActualValue[0];
+      SymbolicExpressionTree parent1 = ParentsParameter.ActualValue[1];
+
+      IRandom random = RandomParameter.ActualValue;
+      ISymbolicExpressionGrammar grammar = SymbolicExpressionGrammarParameter.ActualValue;
+
+      // randomly swap parents to remove a possible bias from selection (e.g. when using gender-specific selection)
+      if (random.NextDouble() < 0.5) {
+        var tmp = parent0;
+        parent0 = parent1;
+        parent1 = tmp;
+      }
+
+      SymbolicExpressionTree result = Cross(random, grammar, parent0, parent1,
+        MaxTreeSizeParameter.ActualValue, MaxTreeHeightParameter.ActualValue);
+      Debug.Assert(result.Size <= MaxTreeSizeParameter.ActualValue.Value);
+      Debug.Assert(result.Height <= MaxTreeHeightParameter.ActualValue.Value);
+      Debug.Assert(grammar.IsValidExpression(result));
       ChildParameter.ActualValue = result;
       return base.Apply();
     }
 
-    protected abstract RealVector Cross(IRandom random, ItemArray<RealVector> parents);
+    protected abstract SymbolicExpressionTree Cross(IRandom random, ISymbolicExpressionGrammar grammar,
+      SymbolicExpressionTree parent0, SymbolicExpressionTree parent1,
+      IntValue maxTreeSize, IntValue maxTreeHeight);
   }
 }
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs	(revision 3236)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/SymbolicExpressionTreeNode.cs	(revision 3237)
@@ -93,4 +93,13 @@
       SubTrees.RemoveAt(index);
     }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      SymbolicExpressionTreeNode clone = new SymbolicExpressionTreeNode(symbol);
+      cloner.RegisterClonedObject(this, clone);
+      foreach (var subtree in SubTrees) {
+        clone.AddSubTree((SymbolicExpressionTreeNode)subtree.Clone(cloner));
+      }
+      return clone;
+    }
   }
 }
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.Designer.cs	(revision 3237)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.Designer.cs	(revision 3237)
@@ -0,0 +1,53 @@
+﻿namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
+  partial class SymbolicExpressionTreeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.textBox = new System.Windows.Forms.TextBox();
+      this.SuspendLayout();
+      // 
+      // textBox
+      // 
+      this.textBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.textBox.Location = new System.Drawing.Point(0, 0);
+      this.textBox.Multiline = true;
+      this.textBox.Name = "textBox";
+      this.textBox.Size = new System.Drawing.Size(150, 150);
+      this.textBox.TabIndex = 0;
+      // 
+      // SymbolicExpressionTreeView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.textBox);
+      this.Name = "SymbolicExpressionTreeView";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox textBox;
+  }
+}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.cs
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.cs	(revision 3237)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.cs	(revision 3237)
@@ -0,0 +1,65 @@
+﻿using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Views {
+  [View("SymbolicExpressionTree View")]
+  [Content(typeof(SymbolicExpressionTree), true)]
+  public partial class SymbolicExpressionTreeView : AsynchronousContentView {
+    public new SymbolicExpressionTree Content {
+      get { return (SymbolicExpressionTree)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public SymbolicExpressionTreeView() {
+      InitializeComponent();
+      Caption = "SymbolicExpressionTree View";
+    }
+
+    public SymbolicExpressionTreeView(SymbolicExpressionTree content)
+      : this() {
+      Content = content;
+    }
+
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        Caption = "SymbolicExpressionTree View";
+        textBox.Text = string.Empty;
+        textBox.Enabled = false;
+      } else {
+        textBox.Text = SymbolicExpression(Content.Root, 0);
+        textBox.Enabled = true;
+      }
+    }
+
+    private static string SymbolicExpression(SymbolicExpressionTreeNode node, int indentLength) {
+      StringBuilder strBuilder = new StringBuilder();
+      strBuilder.Append(' ', indentLength); strBuilder.Append("(");
+      // internal nodes or leaf nodes?
+      if (node.SubTrees.Count > 0) {
+        // symbol on same line as '('
+        strBuilder.AppendLine(node.Symbol.Name);
+        // each subtree expression on a new line
+        // and closing ')' also on new line
+        foreach (var subtree in node.SubTrees) {
+          strBuilder.AppendLine(SymbolicExpression(subtree, indentLength + 2));
+        }
+        strBuilder.Append(' ', indentLength); strBuilder.Append(")");
+      } else {
+        // symbol in the same line with as '(' and ')'
+        strBuilder.Append(node.Symbol.Name);
+        strBuilder.Append(")");
+      }
+      return strBuilder.ToString();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.resx
===================================================================
--- trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.resx	(revision 3237)
+++ trunk/sources/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.3/Views/SymbolicExpressionTreeView.resx	(revision 3237)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
