Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/GrammaticalOptimization.sln
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/GrammaticalOptimization.sln	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/GrammaticalOptimization.sln	(revision 11846)
@@ -15,4 +15,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GrammaticalOptimization.SymbReg", "HeuristicLab.Problems.GrammaticalOptimization.SymbReg\HeuristicLab.Problems.GrammaticalOptimization.SymbReg.csproj", "{17A7A380-86CE-482D-8D22-CBD70CC97F0D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.GeneticProgramming", "HeuristicLab.Algorithms.GeneticProgramming\HeuristicLab.Algorithms.GeneticProgramming.csproj", "{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}"
 EndProject
 Global
@@ -50,4 +52,8 @@
 		{17A7A380-86CE-482D-8D22-CBD70CC97F0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{17A7A380-86CE-482D-8D22-CBD70CC97F0D}.Release|Any CPU.Build.0 = Release|Any CPU
+		{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/HeuristicLab.Algorithms.GeneticProgramming.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/HeuristicLab.Algorithms.GeneticProgramming.csproj	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/HeuristicLab.Algorithms.GeneticProgramming.csproj	(revision 11846)
@@ -0,0 +1,97 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.GeneticProgramming</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.GeneticProgramming</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Selection-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Selection-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.SequentialEngine-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.SequentialEngine-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="OffspringSelectionGP.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="StandardGP.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Algorithms.GrammaticalOptimization\HeuristicLab.Algorithms.GrammaticalOptimization.csproj">
+      <Project>{eea07488-1a51-412a-a52c-53b754a628b3}</Project>
+      <Name>HeuristicLab.Algorithms.GrammaticalOptimization</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Problems.GrammaticalOptimization\HeuristicLab.Problems.GrammaticalOptimization.csproj">
+      <Project>{CB9DCCF6-667E-4A13-B82D-DBD6B45A045E}</Project>
+      <Name>HeuristicLab.Problems.GrammaticalOptimization</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/OffspringSelectionGP.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/OffspringSelectionGP.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/OffspringSelectionGP.cs	(revision 11846)
@@ -0,0 +1,68 @@
+﻿using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Algorithms.GrammaticalOptimization;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.GrammaticalOptimization;
+using HeuristicLab.Selection;
+using HeuristicLab.SequentialEngine;
+using HeuristicLab.Algorithms.GeneticAlgorithm;
+
+namespace HeuristicLab.Algorithms.GeneticProgramming {
+  public class OffspringSelectionGP : SolverBase {
+    public int PopulationSize { get; set; }
+    public double MutationRate { get; set; }
+    public int MaxSolutionSize { get; set; }
+    public int MaxSolutionDepth { get; set; }
+
+    private readonly ISymbolicExpressionTreeProblem problem;
+    private readonly Random random;
+
+    public OffspringSelectionGP(ISymbolicExpressionTreeProblem problem, Random random) {
+      this.problem = problem;
+      this.random = random;
+      // default parameter values
+      PopulationSize = 300;
+      MutationRate = 0.15;
+      MaxSolutionSize = 100;
+      MaxSolutionDepth = 17;
+    }
+
+    public override void Run(int maxEvaluations) {
+      var hlProblem = new GenericSymbExprProblem(problem);
+      hlProblem.Evaluator.SolutionEvaluated += OnSolutionEvaluated; // raise solution evaluated event for each GP solution
+
+      using (var wh = new AutoResetEvent(false)) {
+        var ga = new GeneticAlgorithm.GeneticAlgorithm();
+        ga.Engine = new SequentialEngine.SequentialEngine();
+        ga.ExceptionOccurred += (sender, args) => { Console.WriteLine(args.Value.Message); wh.Set(); };
+        ga.Stopped += (sender, args) => { wh.Set(); };
+
+        ga.Problem = hlProblem;
+        var mutator = (MultiSymbolicExpressionTreeManipulator)ga.MutatorParameter.ValidValues.Single(op => op.Name == "MultiSymbolicExpressionTreeManipulator");
+        foreach (var op in mutator.Operators) {
+          if (op.Name == "ChangeNodeTypeManipulation"
+            || op.Name == "ReplaceBranchManipulation") mutator.Operators.SetItemCheckedState(op, true);
+          else mutator.Operators.SetItemCheckedState(op, false);
+        }
+        ga.Mutator = mutator;
+        ga.Crossover = ga.CrossoverParameter.ValidValues.Single(op => op.Name == "SubtreeSwappingCrossover");
+        ga.Selector = ga.SelectorParameter.ValidValues.Single(op => op.Name == "GenderSpecificSelector");
+
+        ga.PopulationSize.Value = PopulationSize;
+        ga.MaximumGenerations.Value = maxEvaluations / PopulationSize + 1; // one extra generation in case maxEvaluations is not a multiple of PopulationSize
+        ga.MutationProbability.Value = MutationRate;
+
+        ga.SetSeedRandomly = new BoolValue(false);
+        ga.Seed = new IntValue(random.Next());
+
+        ga.Prepare();
+        ga.Start();
+
+        wh.WaitOne();
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/Properties/AssemblyInfo.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/Properties/AssemblyInfo.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/Properties/AssemblyInfo.cs	(revision 11846)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Algorithms.GeneticProgramming")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("FH-Hagenberg")]
+[assembly: AssemblyProduct("HeuristicLab.Algorithms.GeneticProgramming")]
+[assembly: AssemblyCopyright("Copyright © FH-Hagenberg 2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("4ae636d8-8823-4839-8321-d331e2cd1335")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/StandardGP.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/StandardGP.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GeneticProgramming/StandardGP.cs	(revision 11846)
@@ -0,0 +1,72 @@
+﻿using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Algorithms.GrammaticalOptimization;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.GrammaticalOptimization;
+using HeuristicLab.Selection;
+using HeuristicLab.SequentialEngine;
+using HeuristicLab.Algorithms.GeneticAlgorithm;
+
+namespace HeuristicLab.Algorithms.GeneticProgramming {
+  public class StandardGP : SolverBase {
+    public int PopulationSize { get; set; }
+    public double MutationRate { get; set; }
+    public int TournamentGroupSize { get; set; }
+    public int MaxSolutionSize { get; set; }
+    public int MaxSolutionDepth { get; set; }
+
+    private readonly ISymbolicExpressionTreeProblem problem;
+    private readonly Random random;
+
+    public StandardGP(ISymbolicExpressionTreeProblem problem, Random random) {
+      this.problem = problem;
+      this.random = random;
+      // default parameter values
+      PopulationSize = 1000;
+      TournamentGroupSize = 7;
+      MutationRate = 0.15;
+      MaxSolutionSize = 100;
+      MaxSolutionDepth = 17;
+    }
+
+    public override void Run(int maxEvaluations) {
+      var hlProblem = new GenericSymbExprProblem(problem);
+      hlProblem.Evaluator.SolutionEvaluated += OnSolutionEvaluated; // raise solution evaluated event for each GP solution
+
+      using (var wh = new AutoResetEvent(false)) {
+        var ga = new GeneticAlgorithm.GeneticAlgorithm();
+        ga.Engine = new SequentialEngine.SequentialEngine();
+        ga.ExceptionOccurred += (sender, args) => { Console.WriteLine(args.Value.Message); wh.Set(); };
+        ga.Stopped += (sender, args) => { wh.Set(); };
+
+        ga.Problem = hlProblem;
+        var mutator = (MultiSymbolicExpressionTreeManipulator)ga.MutatorParameter.ValidValues.Single(op => op.Name == "MultiSymbolicExpressionTreeManipulator");
+        foreach (var op in mutator.Operators) {
+          if (op.Name == "ChangeNodeTypeManipulation"
+            || op.Name == "ReplaceBranchManipulation") mutator.Operators.SetItemCheckedState(op, true);
+          else mutator.Operators.SetItemCheckedState(op, false);
+        }
+        ga.Mutator = mutator;
+        ga.Crossover = ga.CrossoverParameter.ValidValues.Single(op => op.Name == "SubtreeSwappingCrossover");
+        var selector = (TournamentSelector)ga.SelectorParameter.ValidValues.Single(op => op.Name == "TournamentSelector");
+        selector.GroupSizeParameter.Value = new IntValue(TournamentGroupSize);
+        ga.Selector = selector;
+
+        ga.PopulationSize.Value = PopulationSize;
+        ga.MaximumGenerations.Value = maxEvaluations / PopulationSize + 1; // one extra generation in case maxEvaluations is not a multiple of PopulationSize
+        ga.MutationProbability.Value = MutationRate;
+
+        ga.SetSeedRandomly = new BoolValue(false);
+        ga.Seed = new IntValue(random.Next());
+
+        ga.Prepare();
+        ga.Start();
+
+        wh.WaitOne();
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization.csproj	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization.csproj	(revision 11846)
@@ -45,4 +45,6 @@
     <Compile Include="AlternativesSampler.cs" />
     <Compile Include="AlternativesContextSampler.cs" />
+    <Compile Include="SolverBase.cs" />
+    <Compile Include="ISolver.cs" />
     <Compile Include="SequentialSearch.cs" />
     <Compile Include="ExhaustiveRandomFirstSearch.cs" />
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/ISolver.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/ISolver.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/ISolver.cs	(revision 11846)
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Algorithms.GrammaticalOptimization {
+  public interface ISolver {
+    event Action<string, double> FoundNewBestSolution;
+    event Action<string, double> SolutionEvaluated;
+    void Run(int maxEvaluations);
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/RandomSearch.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/RandomSearch.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/RandomSearch.cs	(revision 11846)
@@ -3,8 +3,5 @@
 
 namespace HeuristicLab.Algorithms.GrammaticalOptimization {
-  public class RandomSearch {
-    public event Action<string, double> FoundNewBestSolution;
-    public event Action<string, double> SolutionEvaluated;
-
+  public class RandomSearch : SolverBase {
     private readonly int maxLen;
     private readonly Random random;
@@ -17,15 +14,9 @@
     }
 
-    public void Run(int maxIterations) {
-      double bestQuality = double.MinValue;
+    public override void Run(int maxIterations) {
       for (int i = 0; i < maxIterations; i++) {
         var sentence = CreateSentence(problem.Grammar).ToString();
         var quality = problem.Evaluate(sentence) / problem.BestKnownQuality(maxLen);
-        RaiseSolutionEvaluated(sentence, quality);
-
-        if (quality > bestQuality) {
-          bestQuality = quality;
-          RaiseFoundNewBestSolution(sentence, quality);
-        }
+        OnSolutionEvaluated(sentence, quality);
       }
     }
@@ -35,13 +26,4 @@
       return grammar.CompleteSentenceRandomly(random, sentence, maxLen);
     }
-
-    private void RaiseSolutionEvaluated(string sentence, double quality) {
-      var handler = SolutionEvaluated;
-      if (handler != null) handler(sentence, quality);
-    }
-    private void RaiseFoundNewBestSolution(string sentence, double quality) {
-      var handler = FoundNewBestSolution;
-      if (handler != null) handler(sentence, quality);
-    }
   }
 }
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SequentialSearch.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SequentialSearch.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SequentialSearch.cs	(revision 11846)
@@ -23,5 +23,5 @@
   //    ... until phrase is terminal
   // 3) Collect reward and update policy (feedback: state of visited rewards from step 2)
-  public class SequentialSearch {
+  public class SequentialSearch : SolverBase {
     // only for storing states so that it is not necessary to allocate new state strings whenever we select a follow state using the policy
     private class TreeNode {
@@ -37,7 +37,4 @@
     }
 
-
-    public event Action<string, double> FoundNewBestSolution;
-    public event Action<string, double> SolutionEvaluated;
 
     private readonly int maxLen;
@@ -52,5 +49,4 @@
     private int maxSearchDepth;
 
-    private double bestQuality;
     private string bestPhrase;
     private readonly List<string> stateChain;
@@ -66,6 +62,5 @@
     }
 
-    public void Run(int maxIterations) {
-      bestQuality = double.MinValue;
+    public override void Run(int maxIterations) {
       Reset();
 
@@ -79,13 +74,12 @@
           if (double.IsNaN(quality)) quality = 0.0;
           Debug.Assert(quality >= 0 && quality <= 1.0);
+
+          if (quality > bestQuality) {
+            bestPhrase = sentence;
+          }
+
+          OnSolutionEvaluated(sentence, quality);
           DistributeReward(quality);
 
-          RaiseSolutionEvaluated(sentence, quality);
-
-          if (quality > bestQuality) {
-            bestQuality = quality;
-            bestPhrase = sentence;
-            RaiseFoundNewBestSolution(sentence, quality);
-          }
         }
       }
@@ -244,13 +238,5 @@
     }
     #endregion
-
-    private void RaiseSolutionEvaluated(string sentence, double quality) {
-      var handler = SolutionEvaluated;
-      if (handler != null) handler(sentence, quality);
-    }
-    private void RaiseFoundNewBestSolution(string sentence, double quality) {
-      var handler = FoundNewBestSolution;
-      if (handler != null) handler(sentence, quality);
-    }
+  
   }
 }
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SolverBase.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SolverBase.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Algorithms.GrammaticalOptimization/SolverBase.cs	(revision 11846)
@@ -0,0 +1,32 @@
+﻿using System;
+using HeuristicLab.Problems.GrammaticalOptimization;
+
+namespace HeuristicLab.Algorithms.GrammaticalOptimization {
+  public abstract class SolverBase : ISolver {
+    public event Action<string, double> FoundNewBestSolution;
+    public event Action<string, double> SolutionEvaluated;
+
+    protected double bestQuality = double.NegativeInfinity;
+
+    protected SolverBase() { }
+
+    public abstract void Run(int maxEvaluations);
+
+    protected virtual void OnSolutionEvaluated(string sentence, double quality) {
+      RaiseSolutionEvaluated(sentence, quality);
+      if (quality > bestQuality) {
+        bestQuality = quality;
+        RaiseFoundNewBestSolution(sentence, quality);
+      }
+    }
+
+    private void RaiseSolutionEvaluated(string sentence, double quality) {
+      var handler = SolutionEvaluated;
+      if (handler != null) handler(sentence, quality);
+    }
+    private void RaiseFoundNewBestSolution(string sentence, double quality) {
+      var handler = FoundNewBestSolution;
+      if (handler != null) handler(sentence, quality);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Common/Extensions.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Common/Extensions.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Common/Extensions.cs	(revision 11846)
@@ -7,4 +7,5 @@
 namespace HeuristicLab.Common {
   public static class Extensions {
+    
     public static bool IsAlmost(this double x, double y) {
       return Math.Abs(x - y) < 1.0e-12;
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.Test/HeuristicLab.Problems.GrammaticalOptimization.Test.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.Test/HeuristicLab.Problems.GrammaticalOptimization.Test.csproj	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.Test/HeuristicLab.Problems.GrammaticalOptimization.Test.csproj	(revision 11846)
@@ -39,4 +39,16 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+    </Reference>
     <Reference Include="HeuristicLab.Problems.Instances-3.3">
       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.csproj	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization.csproj	(revision 11846)
@@ -34,6 +34,45 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.SequentialEngine-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.SequentialEngine-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -43,5 +82,10 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ISymbolicExpressionTreeProblem.cs" />
     <Compile Include="Feature.cs" />
+    <Compile Include="Problems\GrammaticalOptimizationEvaluator.cs" />
+    <Compile Include="Problems\IGrammaticalOptimizationEvaluator.cs" />
+    <Compile Include="Problems\GenericSymbExprProblem.cs" />
+    <Compile Include="Problems\GenericSymbExprGrammar.cs" />
     <Compile Include="Problems\EvenParityProblem.cs" />
     <Compile Include="Problems\ExpressionInterpreter.cs" />
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/IProblem.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/IProblem.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/IProblem.cs	(revision 11846)
@@ -3,6 +3,8 @@
 using System.Linq;
 using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
 namespace HeuristicLab.Problems.GrammaticalOptimization {
+  // represents a grammatical optimization problem
   public interface IProblem {
     double BestKnownQuality(int maxLen);
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/ISymbolicExpressionTreeProblem.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/ISymbolicExpressionTreeProblem.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/ISymbolicExpressionTreeProblem.cs	(revision 11846)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.GrammaticalOptimization {
+  // represents a grammatical optimization problem that can also be used with tree-based GP in HeuristicLab
+  public interface ISymbolicExpressionTreeProblem : IProblem {
+    ISymbolicExpressionGrammar SymbolicExpressionGrammar { get; } // grammar for HL GP
+
+    string ConvertTreeToSentence(ISymbolicExpressionTree tree);
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/ExpressionInterpreter.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/ExpressionInterpreter.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/ExpressionInterpreter.cs	(revision 11846)
@@ -35,5 +35,5 @@
       var d = new double[vars.Length];
       for (int i = 0; i < vars.Length; i++) d[i] = vars[i] ? 1.0 : 0.0;
-      return !(Expr(d, erc).IsAlmost(0));
+      return ! DoubleExtensions.IsAlmost(Expr(d, erc), 0);
     }
 
@@ -63,5 +63,5 @@
     // helper for xor
     private double Not(double x) {
-      return x.IsAlmost(0) ? 1.0 : 0.0;
+      return DoubleExtensions.IsAlmost(x, 0) ? 1.0 : 0.0;
     }
 
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprGrammar.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprGrammar.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprGrammar.cs	(revision 11846)
@@ -0,0 +1,104 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GrammaticalOptimization {
+  [NonDiscoverableType]
+  [StorableClass]
+  [Item("GenericSymbExprGrammar", "Represents a general grammar for grammatical optimization problems.")]
+  public class GenericSymbExprGrammar : SymbolicExpressionGrammar {
+    [StorableClass]
+    [Item("GenericSymbol", "")]
+    public sealed class GenericSymbol : Symbol {
+      private readonly int minimumArity = 1;
+      private readonly int maximumArity = byte.MaxValue;
+
+      public override int MinimumArity { get { return minimumArity; } }
+      public override int MaximumArity { get { return maximumArity; } }
+
+      [StorableConstructor]
+      private GenericSymbol(bool deserializing) : base(deserializing) { }
+      private GenericSymbol(GenericSymbol original, Cloner cloner) : base(original, cloner) { }
+      public override IDeepCloneable Clone(Cloner cloner) {
+        return new GenericSymbol(this, cloner);
+      }
+      public GenericSymbol(char s, int minArity, int maxArity)
+        : base(s.ToString(), string.Empty) {
+        this.minimumArity = minArity;
+        this.maximumArity = maxArity;
+      }
+    }
+
+    [StorableConstructor]
+    public GenericSymbExprGrammar(bool deserializing) : base(deserializing) { }
+
+    public GenericSymbExprGrammar(SymbolicExpressionGrammar original, Cloner cloner) : base(original, cloner) { }
+
+    public GenericSymbExprGrammar(IGrammar grammar)
+      : base(ItemAttribute.GetName(typeof(GenericSymbExprGrammar)), ItemAttribute.GetDescription(typeof(GenericSymbExprGrammar))) {
+
+      var ntSymbs = new List<GenericSymbol>();
+      var tSymbs = new List<GenericSymbol>();
+      // for terminal and nonterminal symbol in the grammar create a symbol class
+      // for non-terminals set the arity and the allowed children
+      // for terminals set arity to 0 and allowed children to empty
+      foreach (var nt in grammar.NonTerminalSymbols) {
+        var ntSymb = CreateSymbol(grammar, nt);
+        AddSymbol(ntSymb);
+        SetSubtreeCount(ntSymb, ntSymb.MinimumArity, ntSymb.MaximumArity);
+        ntSymbs.Add(ntSymb);
+      }
+      foreach (var t in grammar.TerminalSymbols) {
+        var tSymb = new GenericSymbol(t, 0, 0);
+        AddSymbol(tSymb);
+        SetSubtreeCount(tSymb, 0, 0);
+        tSymbs.Add(tSymb);
+      }
+
+      Func<char, GenericSymbol> findSymb = (char s) => {
+        var selectedSymb = ntSymbs.SingleOrDefault(symb => symb.Name == s.ToString());
+        if (selectedSymb != null) return selectedSymb;
+        return tSymbs.SingleOrDefault(symb => symb.Name == s.ToString());
+      };
+
+      // set the sentence symbol as the allowed start symbol
+      AddAllowedChildSymbol(StartSymbol, findSymb(grammar.SentenceSymbol));
+
+      foreach (var nt in ntSymbs) {
+        // either all alts are only a single symbol 
+        // or all alts only use a single symbol (see assertion in CreateSymbol)
+        var alts = grammar.GetAlternatives(nt.Name[0]); // all symbols only have a single character name
+        Debug.Assert(alts.All(alt => alt.Length == 1 || alt.Distinct().Count() == 1));
+
+        foreach (var alt in alts) {
+          Debug.Assert(alt.All(ch => ch == alt[0]));
+          AddAllowedChildSymbol(nt, findSymb(alt.First()));
+        }
+      }
+    }
+
+    private GenericSymbol CreateSymbol(IGrammar g, char s) {
+
+      var minArity = g.GetAlternatives(s).Select(alt => alt.Length).Min();
+      var maxArity = g.GetAlternatives(s).Select(alt => alt.Length).Max();
+      // either the min and max arity is 1 or the alternatives all use the same symbol (hl doesn't know about dependencies between positions in the alternative
+      Debug.Assert(
+        (minArity == 1 && maxArity == 1) ||
+        g.GetAlternatives(s).Select(alt => alt.Distinct()).All(alt => alt.Count() == 1));
+      var symb = new GenericSymbol(s, minArity, maxArity);
+      return symb;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenericSymbExprGrammar(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprProblem.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprProblem.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GenericSymbExprProblem.cs	(revision 11846)
@@ -0,0 +1,79 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GrammaticalOptimization {
+  [NonDiscoverableType]
+  [StorableClass]
+  [Item("GenericSymbExprProblem", "Represents grammatical optimization problems (using a symbolic expression tree encoding).")]
+  public class GenericSymbExprProblem : SingleObjectiveHeuristicOptimizationProblem<IGrammaticalOptimizationEvaluator, ISymbolicExpressionTreeCreator> {
+    #region string consts
+    private const string SymbolicExpressionTreeGrammarParameterName = "SymbolicExpressionTreeGrammar";
+    private const string MaximumSymbolicExpressionTreeDepthParameterName = "MaximumSymbolicExpressionTreeDepth";
+    private const string MaximumSymbolicExpressionTreeLengthParameterName = "MaximumSymbolicExpressionTreeLength";
+
+    #endregion
+
+    #region parameter properties
+    public IValueParameter<ISymbolicExpressionTreeGrammar> SymbolicExpressionTreeGrammarParameter {
+      get { return (IValueParameter<ISymbolicExpressionTreeGrammar>)Parameters[SymbolicExpressionTreeGrammarParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumSymbolicExpressionTreeDepthParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeDepthParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> MaximumSymbolicExpressionTreeLengthParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumSymbolicExpressionTreeLengthParameterName]; }
+    }
+    #endregion
+
+
+    #region properties
+
+    public ISymbolicExpressionTreeGrammar SymbolicExpressionTreeGrammar {
+      get { return SymbolicExpressionTreeGrammarParameter.Value; }
+      set { SymbolicExpressionTreeGrammarParameter.Value = value; }
+    }
+    public IntValue MaximumSymbolicExpressionTreeDepth {
+      get { return MaximumSymbolicExpressionTreeDepthParameter.Value; }
+    }
+    public IntValue MaximumSymbolicExpressionTreeLength {
+      get { return MaximumSymbolicExpressionTreeLengthParameter.Value; }
+    }
+    public new GrammaticalOptimizationEvaluator Evaluator {
+      get { return (GrammaticalOptimizationEvaluator)base.Evaluator; }
+    }
+
+    #endregion
+    [StorableConstructor]
+    public GenericSymbExprProblem(bool deserializing) : base(deserializing) { }
+
+    public GenericSymbExprProblem(GenericSymbExprProblem original, Cloner cloner) : base(original, cloner) { }
+
+    public GenericSymbExprProblem(ISymbolicExpressionTreeProblem problem)
+      : base(new GrammaticalOptimizationEvaluator(problem.ConvertTreeToSentence, problem.Evaluate), new ProbabilisticTreeCreator()) {
+      Parameters.Add(new ValueParameter<ISymbolicExpressionGrammar>(SymbolicExpressionTreeGrammarParameterName, problem.SymbolicExpressionGrammar));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumSymbolicExpressionTreeLengthParameterName, new IntValue(50)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumSymbolicExpressionTreeDepthParameterName, new IntValue(15)));
+
+      Maximization = new BoolValue(true);
+      BestKnownQuality = new DoubleValue(1.0);
+
+      Operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>());
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenericSymbExprProblem(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GrammaticalOptimizationEvaluator.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GrammaticalOptimizationEvaluator.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/GrammaticalOptimizationEvaluator.cs	(revision 11846)
@@ -0,0 +1,67 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GrammaticalOptimization {
+  // this type is not storable because we use a func<ITree,double> for evaluation, which references back to the original grammatical optimization problem
+  [NonDiscoverableType]
+  [Item("GrammaticalOptimizationEvaluator", "Evaluator for grammatical optimization problems (using a symbolic expression tree encoding).")]
+  public class GrammaticalOptimizationEvaluator : SingleSuccessorOperator, IGrammaticalOptimizationEvaluator {
+    public event Action<string, double> SolutionEvaluated;
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ILookupParameter<ISymbolicExpressionTree>)Parameters["SymbolicExpressionTree"]; }
+    }
+
+    private Func<string, double> evalFunc;
+    private Func<ISymbolicExpressionTree, string> toStringFunc;
+
+    public GrammaticalOptimizationEvaluator(GrammaticalOptimizationEvaluator original, Cloner cloner)
+      : base(original, cloner) {
+      this.evalFunc = original.evalFunc;
+    }
+
+    public GrammaticalOptimizationEvaluator(Func<ISymbolicExpressionTree, string> toStringFunc, Func<string, double> evalFunc)
+      : base() {
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality"));
+      Parameters.Add(new LookupParameter<ISymbolicExpressionTree>("SymbolicExpressionTree"));
+      this.evalFunc = evalFunc;
+      this.toStringFunc = toStringFunc;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GrammaticalOptimizationEvaluator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var tree = SymbolicExpressionTreeParameter.ActualValue;
+      var sentence = toStringFunc(tree);
+      var q = evalFunc(sentence);
+      QualityParameter.ActualValue = new DoubleValue(q);
+
+      RaiseSolutionEvaluated(sentence, q);
+
+      return base.Apply();
+    }
+
+    private void RaiseSolutionEvaluated(string sentence, double quality) {
+      var handler = SolutionEvaluated;
+      if (handler != null) handler(sentence, quality);
+    }
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/IGrammaticalOptimizationEvaluator.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/IGrammaticalOptimizationEvaluator.cs	(revision 11846)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/IGrammaticalOptimizationEvaluator.cs	(revision 11846)
@@ -0,0 +1,18 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.GrammaticalOptimization {
+  public interface IGrammaticalOptimizationEvaluator : ISingleObjectiveEvaluator, ISymbolicExpressionTreeOperator {
+    ILookupParameter<ISymbolicExpressionTree> SymbolicExpressionTreeParameter { get; } 
+  }
+}
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/SymbolicRegressionPoly10Problem.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/SymbolicRegressionPoly10Problem.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/Problems/SymbolicRegressionPoly10Problem.cs	(revision 11846)
@@ -3,4 +3,5 @@
 using System.Collections.Generic;
 using System.Collections.Specialized;
+using System.Diagnostics;
 using System.Linq;
 using System.Net;
@@ -9,7 +10,8 @@
 using System.Text;
 using HeuristicLab.Common;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 
 namespace HeuristicLab.Problems.GrammaticalOptimization {
-  public class SymbolicRegressionPoly10Problem : IProblem {
+  public class SymbolicRegressionPoly10Problem : ISymbolicExpressionTreeProblem {
     //    private const string grammarString = @"
     //    G(E):
@@ -22,4 +24,33 @@
     ";
 
+    // for tree-based GP in HL we need a different grammar for the same language
+    // E = expr, S = sum, P = product
+    private const string hlGrammarString = @"
+    G(E):
+    E -> S | P | a | b | c | d | e | f | g | h | i | j
+    S -> EE | EEE
+    P -> EE | EEE
+    ";
+    // mininmal tree for the optimal expr (40 nodes)
+    // E S
+    //     E S
+    //         E P 
+    //           E a E b
+    //         E P 
+    //           E c E d
+    //         E P 
+    //           E e E f
+    //     E S
+    //         E P 
+    //           E a E g E i
+    //         E P 
+    //           E c E f E j
+
+    private SymbolicExpressionGrammar symbExprGrammar;
+    public ISymbolicExpressionGrammar SymbolicExpressionGrammar {
+      get {
+        return symbExprGrammar;
+      }
+    }
 
     private readonly IGrammar grammar;
@@ -31,4 +62,5 @@
     public SymbolicRegressionPoly10Problem() {
       this.grammar = new Grammar(grammarString);
+      this.symbExprGrammar = new GenericSymbExprGrammar(new Grammar(hlGrammarString));
 
       this.N = 500;
@@ -71,5 +103,4 @@
       return HeuristicLab.Common.Extensions.RSq(y, Enumerable.Range(0, N).Select(i => interpreter.Interpret(sentence, x[i])).ToArray());
     }
-
 
 
@@ -130,4 +161,36 @@
     }
 
+    public string ConvertTreeToSentence(ISymbolicExpressionTree tree) {
+      var sb = new StringBuilder();
+
+      TreeToSentence(tree.Root.GetSubtree(0).GetSubtree(0), sb);
+
+      return sb.ToString();
+    }
+
+    private void TreeToSentence(ISymbolicExpressionTreeNode treeNode, StringBuilder sb) {
+      if (treeNode.SubtreeCount == 0) {
+        // terminal
+        sb.Append(treeNode.Symbol.Name);
+      } else {
+        string op = string.Empty;
+        switch (treeNode.Symbol.Name) {
+          case "S": op = "+"; break;
+          case "P": op = "*"; break;
+          default: {
+              Debug.Assert(treeNode.SubtreeCount == 1);
+              break;
+            }
+        }
+        // nonterminal
+        if (op == "+") sb.Append("(");
+        TreeToSentence(treeNode.Subtrees.First(), sb);
+        foreach (var subTree in treeNode.Subtrees.Skip(1)) {
+          sb.Append(op);
+          TreeToSentence(subTree, sb);
+        }
+        if (op == "+") sb.Append(")");
+      }
+    }
   }
 }
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/SentenceSetStatistics.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/SentenceSetStatistics.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/HeuristicLab.Problems.GrammaticalOptimization/SentenceSetStatistics.cs	(revision 11846)
@@ -41,11 +41,21 @@
     public override string ToString() {
       return
-        string.Format("Sentences: {0,10} avg.-quality {1,7:F5} best {2,7:F5} {3,2} {4,10} {5} first {6,7:F5} {7} last {8,7:F5} {9}",
+        string.Format("Sentences: {0,10} avg.-quality {1,7:F5} best {2,7:F5} {3,2} {4,10} {5,30} first {6,7:F5} {7,20} last {8,7:F5} {9,20}",
       NumberOfSentences, AverageQuality,
-      BestSentenceQuality, BestSentenceQuality.IsAlmost(1.0)?1.0:0.0, 
-      BestSentenceIndex, BestSentence,
-      FirstSentenceQuality, FirstSentence,
-      LastSentenceQuality, LastSentence
+      BestSentenceQuality, DoubleExtensions.IsAlmost(BestSentenceQuality, 1.0) ? 1.0 : 0.0,
+      BestSentenceIndex, TrimToSize(BestSentence, 30),
+      FirstSentenceQuality, TrimToSize(FirstSentence, 20),
+      LastSentenceQuality, TrimToSize(LastSentence, 20)
      );
+    }
+
+    private string TrimToSize(string s, int len) {
+      if (s.Length < len) return s;
+      else {
+        var sb = new StringBuilder(len);
+        sb.Append(s.Substring(0, len - 3));
+        sb.Append("...");
+        return sb.ToString();
+      }
     }
   }
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Main.csproj	(revision 11846)
@@ -36,11 +36,9 @@
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3">
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
@@ -52,4 +50,8 @@
       <Project>{24408F7D-EE0F-4886-A08B-EC324D662E47}</Project>
       <Name>HeuristicLab.Algorithms.Bandits</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Algorithms.GeneticProgramming\HeuristicLab.Algorithms.GeneticProgramming.csproj">
+      <Project>{14BEC23F-63FD-4954-B8AE-E2F4962E9B57}</Project>
+      <Name>HeuristicLab.Algorithms.GeneticProgramming</Name>
     </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Algorithms.GrammaticalOptimization\HeuristicLab.Algorithms.GrammaticalOptimization.csproj">
Index: /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs
===================================================================
--- /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs	(revision 11845)
+++ /branches/HeuristicLab.Problems.GrammaticalOptimization/Main/Program.cs	(revision 11846)
@@ -1,9 +1,8 @@
 using System;
 using System.Collections.Generic;
-using System.Data;
 using System.Diagnostics;
 using System.Globalization;
-using System.Linq;
 using System.Text;
+using System.Threading;
 using System.Threading.Tasks;
 using HeuristicLab.Algorithms.Bandits;
@@ -11,9 +10,10 @@
 using HeuristicLab.Algorithms.Bandits.GrammarPolicies;
 using HeuristicLab.Algorithms.Bandits.Models;
+using HeuristicLab.Algorithms.GeneticProgramming;
 using HeuristicLab.Algorithms.GrammaticalOptimization;
 using HeuristicLab.Problems.GrammaticalOptimization;
-using HeuristicLab.Problems.GrammaticalOptimization.SymbReg;
 using BoltzmannExplorationPolicy = HeuristicLab.Algorithms.Bandits.BanditPolicies.BoltzmannExplorationPolicy;
 using EpsGreedyPolicy = HeuristicLab.Algorithms.Bandits.BanditPolicies.EpsGreedyPolicy;
+using IProblem = HeuristicLab.Problems.GrammaticalOptimization.IProblem;
 using RandomPolicy = HeuristicLab.Algorithms.Bandits.BanditPolicies.RandomPolicy;
 using UCTPolicy = HeuristicLab.Algorithms.Bandits.BanditPolicies.UCTPolicy;
@@ -25,5 +25,6 @@
 
       //RunDemo();
-      RunGridTest();
+      RunGpDemo();
+      // RunGridTest();
     }
 
@@ -296,4 +297,37 @@
         (double)sw.ElapsedMilliseconds * 1000 / maxIterations);
     }
+
+    public static void RunGpDemo() {
+
+      int iterations = 0;
+      const int maxIterations = 100000;
+      const int seed = 31415;
+      var globalStatistics = new SentenceSetStatistics();
+
+      var gp = new StandardGP(new SymbolicRegressionPoly10Problem(), new Random(seed));
+      gp.FoundNewBestSolution += (sentence, quality) => {
+        Console.WriteLine("{0}", globalStatistics);
+      };
+      gp.SolutionEvaluated += (sentence, quality) => {
+        iterations++;
+        globalStatistics.AddSentence(sentence, quality);
+
+        if (iterations % 10000 == 0) {
+          Console.WriteLine("{0}", globalStatistics);
+        }
+      };
+
+      var sw = new Stopwatch();
+
+      sw.Start();
+      gp.Run(maxIterations);
+      sw.Stop();
+
+      Console.WriteLine(globalStatistics);
+      Console.WriteLine("{0:F2} sec {1,10:F1} sols/sec {2,10:F1} ns/sol",
+        sw.Elapsed.TotalSeconds,
+        maxIterations / (double)sw.Elapsed.TotalSeconds,
+        (double)sw.ElapsedMilliseconds * 1000 / maxIterations);
+    }
   }
 }
