Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Build.cmd
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Build.cmd	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Build.cmd	(revision 12909)
@@ -0,0 +1,94 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=0
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+  ECHO Solution file %SELECTED% could not be found.
+  GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+  CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+  SET SELECTED=%SOLUTIONS.1%
+  ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+  GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number: 
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+  IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"==""  GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Release]: 
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Release
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+  
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :main
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims=	 " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+  IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%"=="1" (
+  ECHO Cleaning ...
+  %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Rebuild /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj	(revision 12909)
@@ -0,0 +1,222 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{9D804CEF-4827-404F-834D-68540FA26551}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
+    <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, 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.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, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
+    </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, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Interfaces\IStateFunction.cs" />
+    <Compile Include="Interfaces\IQualityFunction.cs" />
+    <Compile Include="Interfaces\ITabularQualityFunction.cs" />
+    <Compile Include="Interfaces\ISymbolicExpressionConstructionPolicy.cs" />
+    <Compile Include="IteratedSymbolicExpressionConstruction.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Policies\BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs" />
+    <Compile Include="Policies\EpsGreedySymbolicExpressionConstructionPolicy.cs" />
+    <Compile Include="Policies\SymbolicExpressionConstructionPolicyBase.cs" />
+    <Compile Include="Policies\RandomSymbolicExpressionConstructionPolicy.cs" />
+    <Compile Include="Policies\UcbSymbolicExpressionConstructionPolicy.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="QualityFunctions\TabularAvgQualityFunction.cs" />
+    <Compile Include="QualityFunctions\TabularMaxQualityFunction.cs" />
+    <Compile Include="SearchTree.cs" />
+    <Compile Include="StateFunctions\ParentChildStateFunction.cs" />
+    <Compile Include="StateFunctions\DefaultStateFunction.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <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>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IQualityFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IQualityFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IQualityFunction.cs	(revision 12909)
@@ -0,0 +1,15 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // maps a state action pair to a quality
+  public interface IQualityFunction : IStatefulItem {
+    double Q(object state, int action);
+    void Update(object state, int action, double observedQuality);
+    IStateFunction StateFunction { get; }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/IStateFunction.cs	(revision 12909)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // creates a state from the information available at sequential derivation steps of symbolic expression trees
+  public interface IStateFunction : IItem {
+    object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parentNode, int childIdx);
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ISymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ISymbolicExpressionConstructionPolicy.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ISymbolicExpressionConstructionPolicy.cs	(revision 12909)
@@ -0,0 +1,14 @@
+﻿using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Drawing.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  public interface ISymbolicExpressionConstructionPolicy : IItem {
+    void Initialize(SymbolicExpressionTreeProblem problem, IRandom random);
+    ISymbolicExpressionTree Sample(out IEnumerable<Tuple<object, int>> stateActionSequence);
+    void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality);
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ITabularQualityFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ITabularQualityFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Interfaces/ITabularQualityFunction.cs	(revision 12909)
@@ -0,0 +1,13 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // maps a state action pair to a quality
+  // represents quality functions that use a table representation for states & actions and can therefore return the number of tries for each state/action pair
+  public interface ITabularQualityFunction : IQualityFunction {
+    int Tries(object state, int action);
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/IteratedSymbolicExpressionConstruction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/IteratedSymbolicExpressionConstruction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/IteratedSymbolicExpressionConstruction.cs	(revision 12909)
@@ -0,0 +1,225 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ * and the BEACON Center for the Study of Evolution in Action.
+ * 
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using HeuristicLab.Analysis;
+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;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [Item("Iterated Symbolic Expression Construction", "Generates symbolic expression trees iteratively.")]
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.SingleSolutionAlgorithms, Priority = 400)]
+  public class IteratedSymbolicExpressionConstruction : BasicAlgorithm {
+    public override Type ProblemType {
+      get { return typeof(SymbolicExpressionTreeProblem); }
+    }
+    public new SymbolicExpressionTreeProblem Problem {
+      get { return (SymbolicExpressionTreeProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    #region ParameterNames
+    private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
+    private const string SeedParameterName = "Seed";
+    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
+    private const string ResultUpdateIntervalParameterName = "ResultUpdateInterval";
+    private const string PolicyParameterName = "Policy";
+    #endregion
+
+    #region ParameterProperties
+    public IFixedValueParameter<IntValue> MaximumEvaluationsParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[MaximumEvaluationsParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> SeedParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[SeedParameterName]; }
+    }
+    public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[SetSeedRandomlyParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> ResultUpdateIntervalParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[ResultUpdateIntervalParameterName]; }
+    }
+    public IValueParameter<ISymbolicExpressionConstructionPolicy> PolicyParameter {
+      get {
+        return (IValueParameter<ISymbolicExpressionConstructionPolicy>)Parameters[PolicyParameterName];
+      }
+    }
+    #endregion
+
+    #region Properties
+    public int MaximumEvaluations {
+      get { return MaximumEvaluationsParameter.Value.Value; }
+      set { MaximumEvaluationsParameter.Value.Value = value; }
+    }
+    public int Seed {
+      get { return SeedParameter.Value.Value; }
+      set { SeedParameter.Value.Value = value; }
+    }
+    public bool SetSeedRandomly {
+      get { return SetSeedRandomlyParameter.Value.Value; }
+      set { SetSeedRandomlyParameter.Value.Value = value; }
+    }
+    public int ResultUpdateInterval {
+      get { return ResultUpdateIntervalParameter.Value.Value; }
+      set { ResultUpdateIntervalParameter.Value.Value = value; }
+    }
+    #endregion
+
+    #region ResultsProperties
+    public double ResultsBestQuality {
+      get { return ((DoubleValue)Results["Best Quality"].Value).Value; }
+    }
+    public int ResultsBestFoundOnEvaluation {
+      get { return ((IntValue)Results["Evaluation Best Solution Was Found"].Value).Value; }
+    }
+    public int ResultsEvaluations {
+      get { return ((IntValue)Results["Evaluations"].Value).Value; }
+    }
+    public DataTable ResultsQualities {
+      get { return ((DataTable)Results["Qualities"].Value); }
+    }
+    public DataRow ResultsQualitiesBest {
+      get { return ResultsQualities.Rows["Best Quality"]; }
+    }
+    public DataRow ResultQualitiesAverage {
+      get { return ResultsQualities.Rows["Average Quality"]; }
+    }
+    #endregion
+
+    private readonly IRandom random = new MersenneTwister();
+
+
+    [StorableConstructor]
+    protected IteratedSymbolicExpressionConstruction(bool deserializing) : base(deserializing) { }
+
+    protected IteratedSymbolicExpressionConstruction(IteratedSymbolicExpressionConstruction original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IteratedSymbolicExpressionConstruction(this, cloner);
+    }
+
+    public IteratedSymbolicExpressionConstruction() {
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(500000)));
+      Parameters.Add(new FixedValueParameter<IntValue>(ResultUpdateIntervalParameterName, "The update interval for the result values in number of evaluations", new IntValue(100)));
+      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue
+(true)));
+      Parameters.Add(new ValueParameter<ISymbolicExpressionConstructionPolicy>(PolicyParameterName, "The policy to use for exploring the search tree", new UcbSymbolicExpressionConstructionPolicy()));
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      // TODO minimization problems
+      if (!Problem.Maximization) throw new NotSupportedException("Minimization problems are not supported");
+
+      // Set up the algorithm
+      if (SetSeedRandomly) Seed = new System.Random().Next();
+      random.Reset(Seed);
+
+      //var policy = new RandomSymbolicExpressionConstructionPolicy(Problem, random);
+      //var policy = new EpsGreedySymbolicExpressionConstructionPolicy<string>(Problem, random, new TabularMaxQualityFunction<string>(new DefaultStateFunction()));
+      //var policy = new EpsGreedySymbolicExpressionConstructionPolicy(Problem, random, new TabularAvgQualityFunction<string>(new DefaultStateFunction()));
+      //var policy = new EpsGreedySymbolicExpressionConstructionPolicy(Problem, random, new TabularMaxQualityFunction<string>(new ParentChildStateFunction()));
+      //var policy = new EpsGreedySymbolicExpressionConstructionPolicy(Problem, random, new TabularAvgQualityFunction<string>(new ParentChildStateFunction()));
+      //var policy = new UcbSymbolicExpressionConstructionPolicy<string>(Problem, random, new TabularMaxQualityFunction<string>(new DefaultStateFunction()));
+      //var policy = new UcbWithStateAggregationSymbolicExpressionConstructionPolicy(Problem, random, 40);
+
+      var policy = PolicyParameter.Value;
+      policy.Initialize(Problem, random);
+
+      IntValue evaluations = new IntValue(0);
+      DoubleValue bestQuality = new DoubleValue(Double.NegativeInfinity);
+      IntValue bestFoundOnEvaluation = new IntValue(0);
+
+      // Set up the results display
+      Results.Add(new Result("Evaluations", evaluations));
+      Results.Add(new Result("Best Quality", bestQuality));
+      Results.Add(new Result("Evaluation Best Solution Was Found", bestFoundOnEvaluation));
+
+      var table = new DataTable("Qualities");
+      var bestQualityRow = new DataRow("Best Quality");
+      table.Rows.Add(bestQualityRow);
+
+      var currentQualityRow = new DataRow("Average Quality");
+      currentQualityRow.VisualProperties.LineStyle = DataRowVisualProperties.DataRowLineStyle.Dot;
+      table.Rows.Add(currentQualityRow);
+
+      Results.Add(new Result("Qualities", table));
+
+      // for problem-specific analyzer
+      ISymbolicExpressionTree[] solutions = new ISymbolicExpressionTree[1];
+      double[] qualities = new double[1];
+
+      // the algorithm
+      // Loop until iteration limit reached or canceled.
+      int evals = 0;
+      double sumQuality = 0; // for average quality calculation
+      int resultUpdateInterval = ResultUpdateInterval;
+      while (evals < MaximumEvaluations) {
+        double quality = double.NaN;
+        ISymbolicExpressionTree tree = null;
+        IEnumerable<Tuple<object, int>> actionSequence;
+        tree = policy.Sample(out actionSequence);
+        quality = Problem.Evaluate(tree, random);
+        evals++;
+        sumQuality += quality;
+
+        policy.Update(actionSequence, quality);
+
+        // update statistics results in regular update intervals
+        if ((evals - 1) % resultUpdateInterval == resultUpdateInterval - 1) {
+          evaluations.Value = evals;
+          bestQualityRow.Values.Add(bestQuality.Value);
+          currentQualityRow.Values.Add(sumQuality / (double)resultUpdateInterval);
+          sumQuality = 0;
+        }
+
+        // update best solution results whenever a new better solution is found
+        if (Problem.IsBetter(quality, bestQuality.Value)) {
+          bestQuality.Value = quality;
+          bestFoundOnEvaluation.Value = evals;
+
+          // for problem-specific analyzer
+          solutions[0] = tree;
+          qualities[0] = quality;
+        }
+
+        // run problem-specific analyzer in each iteration
+        Problem.Analyze(solutions, qualities, Results, random);
+
+        cancellationToken.ThrowIfCancellationRequested();
+      }
+    }
+
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Plugin.cs.frame
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Plugin.cs.frame	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Plugin.cs.frame	(revision 12909)
@@ -0,0 +1,41 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [Plugin("HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction","Provides algorithms for optimization of symbolic expression tree problems.", "3.3.0.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.SymbolicExpressionTreeEncoding","3.4")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabAlgorithmsIteratedSymbolicExpressionConstructionPlugin : PluginBase {
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/BoltzmannExplorationSymbolicExpressionConstructionPolicy.cs	(revision 12909)
@@ -0,0 +1,82 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("BoltzmannExplorationSymbolicExpressionConstructionPolicy", "")]
+  public class BoltzmannExplorationSymbolicExpressionConstructionPolicy : SymbolicExpressionConstructionPolicyBase {
+    public double Beta {
+      get { return ((IFixedValueParameter<DoubleValue>)Parameters["Beta"]).Value.Value; }
+      set { ((IFixedValueParameter<DoubleValue>)Parameters["Beta"]).Value.Value = value; }
+    }
+
+    public ITabularQualityFunction QualityFunction {
+      get {
+        return ((IValueParameter<ITabularQualityFunction>)Parameters["Quality function"]).Value;
+      }
+      set { ((IValueParameter<ITabularQualityFunction>)Parameters["Quality function"]).Value = value; }
+    }
+
+
+    protected BoltzmannExplorationSymbolicExpressionConstructionPolicy(BoltzmannExplorationSymbolicExpressionConstructionPolicy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected BoltzmannExplorationSymbolicExpressionConstructionPolicy(bool deserializing) : base(deserializing) { }
+
+
+    public BoltzmannExplorationSymbolicExpressionConstructionPolicy()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Beta", "The weighting factor beta", new DoubleValue(1.0)));
+      Parameters.Add(new ValueParameter<ITabularQualityFunction>("Quality function", "The quality function to use", new TabularAvgQualityFunction()));
+    }
+
+    protected sealed override int Select(object state, IEnumerable<int> actions, IRandom random) {
+
+      // find best action
+      var bestActions = new List<int>();
+      var bestQuality = double.NegativeInfinity;
+      if (actions.Any(a => QualityFunction.Tries(state, a) == 0)) {
+        return actions.Where(a => QualityFunction.Tries(state, a) == 0).SampleRandom(random, 1).First();
+      }
+
+      // windowing
+      var max = actions.Select(a => QualityFunction.Q(state, a)).Max();
+      var min = actions.Select(a => QualityFunction.Q(state, a)).Min();
+      double range = max - min;
+      if (range.IsAlmost(0.0)) return actions.SampleRandom(random, 1).First();
+
+      var w = from a in actions
+              select Math.Exp(Beta * (QualityFunction.Q(state, a) - min) / range);
+
+      return actions.SampleProportional(random, 1, w).First();
+
+    }
+
+    public sealed override void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality) {
+      foreach (var t in stateActionSequence) {
+        var state = t.Item1;
+        var action = t.Item2;
+        QualityFunction.Update(state, action, quality);
+      }
+    }
+
+    protected override object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parent, int childIdx) {
+      return QualityFunction.StateFunction.CreateState(root, actions, parent, childIdx);
+    }
+
+    public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
+      return new BoltzmannExplorationSymbolicExpressionConstructionPolicy(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/EpsGreedySymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/EpsGreedySymbolicExpressionConstructionPolicy.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/EpsGreedySymbolicExpressionConstructionPolicy.cs	(revision 12909)
@@ -0,0 +1,83 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("EpsGreedySymbolicExpressionConstructionPolicy", "")]
+  public class EpsGreedySymbolicExpressionConstructionPolicy : SymbolicExpressionConstructionPolicyBase {
+
+    public double Eps {
+      get { return ((IFixedValueParameter<DoubleValue>)Parameters["Eps"]).Value.Value; }
+      set { ((IFixedValueParameter<DoubleValue>)Parameters["Eps"]).Value.Value = value; }
+    }
+
+    public IQualityFunction QualityFunction {
+      get {
+        return ((IValueParameter<IQualityFunction>)Parameters["Quality function"]).Value;
+      }
+      set { ((IValueParameter<IQualityFunction>)Parameters["Quality function"]).Value = value; }
+    }
+
+    public EpsGreedySymbolicExpressionConstructionPolicy()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("Eps", "The fraction of random pulls", new PercentValue(0.1, true)));
+      Parameters.Add(new ValueParameter<IQualityFunction>("Quality function", "The quality function to use", new TabularAvgQualityFunction()));
+    }
+
+    protected override int Select(object state, IEnumerable<int> actions, IRandom random) {
+      if (random.NextDouble() < Eps) {
+        return actions.SampleRandom(random, 1).First();
+      }
+
+      // find best action
+      var bestActions = new List<int>();
+      var bestQuality = double.NegativeInfinity;
+      foreach (var a in actions) {
+        double quality = QualityFunction.Q(state, a);
+
+        if (quality >= bestQuality) {
+          if (quality > bestQuality) {
+            bestActions.Clear();
+            bestQuality = quality;
+          }
+          bestActions.Add(a);
+        }
+      }
+      return bestActions.SampleRandom(random, 1).First();
+    }
+
+    public override void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality) {
+      foreach (var t in stateActionSequence) {
+        var state = t.Item1;
+        var action = t.Item2;
+        QualityFunction.Update(state, action, quality);
+      }
+    }
+
+    protected override object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parent, int childIdx) {
+      return QualityFunction.StateFunction.CreateState(root, actions, parent, childIdx);
+    }
+
+    #region IItem
+    protected EpsGreedySymbolicExpressionConstructionPolicy(EpsGreedySymbolicExpressionConstructionPolicy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected EpsGreedySymbolicExpressionConstructionPolicy(bool deserializing) : base(deserializing) { }
+
+    public override HeuristicLab.Common.IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
+      return new EpsGreedySymbolicExpressionConstructionPolicy(this, cloner);
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/RandomSymbolicExpressionConstructionPolicy.cs	(revision 12909)
@@ -0,0 +1,45 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("RandomSymbolicExpressionConstructionPolicy", "")]
+  public class RandomSymbolicExpressionConstructionPolicy : SymbolicExpressionConstructionPolicyBase {
+
+    public RandomSymbolicExpressionConstructionPolicy()
+      : base() {
+    }
+
+    protected override int Select(object state, IEnumerable<int> actions, IRandom random) {
+      return actions.SampleRandom(random, 1).First();
+    }
+
+    public override void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality) {
+      // ignore
+    }
+
+    protected override object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parent, int childIdx) {
+      return null; // doesn't use state information
+    }
+
+    #region IItem
+    protected RandomSymbolicExpressionConstructionPolicy(RandomSymbolicExpressionConstructionPolicy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected RandomSymbolicExpressionConstructionPolicy(bool deserializing) : base(deserializing) { }
+
+    public override HeuristicLab.Common.IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
+      return new RandomSymbolicExpressionConstructionPolicy(this, cloner);
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/SymbolicExpressionConstructionPolicyBase.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/SymbolicExpressionConstructionPolicyBase.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/SymbolicExpressionConstructionPolicyBase.cs	(revision 12909)
@@ -0,0 +1,138 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Net.NetworkInformation;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // this class is a base class for symbolic expression construction policies
+  // it filters allowed actions based on tree length constraint
+  // and keeps all visited derivation paths in memory to prevent sampling of duplicates
+  [StorableClass]
+  public abstract class SymbolicExpressionConstructionPolicyBase : ParameterizedNamedItem, ISymbolicExpressionConstructionPolicy {
+    [Storable]
+    public SymbolicExpressionTreeProblem Problem { get; private set; }
+    [Storable]
+    public IRandom Random { get; private set; }
+    private SearchTree searchTree;
+
+    private class Slot {
+      public ISymbolicExpressionTreeNode parent;
+      public int childIdx;
+      public int minSize;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      searchTree = new SearchTree();
+    }
+    protected SymbolicExpressionConstructionPolicyBase(SymbolicExpressionConstructionPolicyBase original, Cloner cloner)
+      : base(original, cloner) {
+      this.Problem = cloner.Clone(original.Problem);
+      this.Random = cloner.Clone(original.Random);
+
+      // search tree is not cloned or stored
+      searchTree = new SearchTree();
+    }
+
+    [StorableConstructor]
+    protected SymbolicExpressionConstructionPolicyBase(bool deserializing) : base(deserializing) { }
+
+    protected SymbolicExpressionConstructionPolicyBase() {
+    }
+
+    public virtual void Initialize(SymbolicExpressionTreeProblem problem, IRandom random) {
+      this.Problem = problem;
+      this.Random = random;
+      this.searchTree = new SearchTree(); // represents all realized actionSequences as a prefix tree 
+    }
+
+    public ISymbolicExpressionTree Sample(out IEnumerable<Tuple<object, int>> stateActionSequence) {
+      var actions = new List<int>();
+      var states = new List<object>();
+
+      var openSlots = new Stack<Slot>();
+      var g = Problem.Encoding.Grammar;
+      var root = g.ProgramRootSymbol.CreateTreeNode();
+      int maxDepth = Problem.Encoding.TreeDepthParameter.Value.Value;
+      int maxLen = Problem.Encoding.TreeLengthParameter.Value.Value;
+
+
+      Contract.Assert(Problem.Encoding.FunctionDefinitions == 0);
+      openSlots.Push(new Slot() { parent = root, childIdx = 0, minSize = 2 }); // at least two nodes are necessary below root
+
+      // tree size lower bound is the current tree size + the sum of the minimal size for all open slots
+      int treeSize = 1;
+
+      searchTree.ResetPosition();
+
+      while (openSlots.Any()) {
+        var next = openSlots.Pop();
+        var parent = next.parent;
+        var childIdx = next.childIdx;
+
+        // states might be defined differently be different policies
+        // this allows policies to calculate the state as a function of the current tree and the position where it is changed,
+        // or as a function of the list of actions so far, 
+        // or as a function of both
+        var currentState = CreateState(root, actions, parent, childIdx);
+        states.Add(currentState);
+
+
+        // TODO: only filter the first time later use info from search tree
+        var alts = g.GetAllowedChildSymbols(parent.Symbol, childIdx)
+          .Where(a => treeSize + g.GetMinimumExpressionLength(a) + openSlots.Select(e => e.minSize).Sum() <= maxLen)
+          .ToArray();
+
+        if (searchTree.IsLeafNode()) {
+          searchTree.ExpandCurrentNode(alts);
+        }
+
+        if (!searchTree.PossibleActions.Any()) {
+          throw new InvalidProgramException(string.Format("Couldn't construct a valid tree of maximum length {0} or all possible trees have been visited", maxLen));
+        }
+
+        // select a symbol randomly for the child 
+        // select random alternative
+        var selectedIdx = Select(currentState, searchTree.PossibleActions, Random);
+        actions.Add(selectedIdx);
+
+        // and add child node to parent
+        var childNode = alts[selectedIdx].CreateTreeNode();
+        if (childNode.HasLocalParameters) childNode.ResetLocalParameters(Random);
+
+        Contract.Assert(parent.SubtreeCount == childIdx);
+        parent.AddSubtree(childNode); // enforce left-canonical derivation
+        treeSize++;
+
+        // push new slots 
+        for (int chIdx = childNode.Symbol.MinimumArity - 1; chIdx >= 0; chIdx--) {
+          int minForChild = g.GetAllowedChildSymbols(childNode.Symbol, chIdx).Min(a => g.GetMinimumExpressionLength(a)); // min length of all possible alts for the slot
+          openSlots.Push(new Slot() { parent = childNode, childIdx = chIdx, minSize = minForChild });
+        }
+
+        // if this is the last slot we never have to revisit selectedIdx
+        if (!openSlots.Any()) {
+          searchTree.RemoveBranch(selectedIdx);
+        } else {
+          searchTree.Follow(selectedIdx);
+        }
+      }
+
+      stateActionSequence = states.Zip(actions, Tuple.Create);
+      return new SymbolicExpressionTree(root);
+    }
+
+
+    protected abstract int Select(object state, IEnumerable<int> possibleActions, IRandom random);
+    public abstract void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality);
+
+    protected abstract object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parent, int childIdx);
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/UcbSymbolicExpressionConstructionPolicy.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/UcbSymbolicExpressionConstructionPolicy.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Policies/UcbSymbolicExpressionConstructionPolicy.cs	(revision 12909)
@@ -0,0 +1,84 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("UcbSymbolicExpressionConstructionPolicy", "")]
+  public class UcbSymbolicExpressionConstructionPolicy : SymbolicExpressionConstructionPolicyBase {
+    public double R {
+      get { return ((IFixedValueParameter<DoubleValue>)Parameters["R"]).Value.Value; }
+      set { ((IFixedValueParameter<DoubleValue>)Parameters["R"]).Value.Value = value; }
+    }
+
+    public ITabularQualityFunction QualityFunction {
+      get {
+        return ((IValueParameter<ITabularQualityFunction>)Parameters["Quality function"]).Value;
+      }
+      set { ((IValueParameter<ITabularQualityFunction>)Parameters["Quality function"]).Value = value; }
+    }
+
+
+    protected UcbSymbolicExpressionConstructionPolicy(UcbSymbolicExpressionConstructionPolicy original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    [StorableConstructor]
+    protected UcbSymbolicExpressionConstructionPolicy(bool deserializing) : base(deserializing) { }
+
+
+    public UcbSymbolicExpressionConstructionPolicy()
+      : base() {
+      Parameters.Add(new FixedValueParameter<DoubleValue>("R", "The weighting factor for the confidence bound (should be scaled based on the range or the fitness values)", new DoubleValue(1.0)));
+      Parameters.Add(new ValueParameter<ITabularQualityFunction>("Quality function", "The quality function to use", new TabularAvgQualityFunction()));
+    }
+
+    protected sealed override int Select(object state, IEnumerable<int> actions, IRandom random) {
+
+      // find best action
+      var bestActions = new List<int>();
+      var bestQuality = double.NegativeInfinity;
+      int totalTries = actions.Sum(a => QualityFunction.Tries(state, a));
+      foreach (var a in actions) {
+        double quality;
+        if (QualityFunction.Tries(state, a) == 0) {
+          quality = double.PositiveInfinity;
+        } else {
+          quality = QualityFunction.Q(state, a) + R * Math.Sqrt((2 * Math.Log(totalTries)) / QualityFunction.Tries(state, a));
+        }
+        if (quality >= bestQuality) {
+          if (quality > bestQuality) {
+            bestActions.Clear();
+            bestQuality = quality;
+          }
+          bestActions.Add(a);
+        }
+      }
+      return bestActions.SampleRandom(random, 1).First();
+    }
+
+    public sealed override void Update(IEnumerable<Tuple<object, int>> stateActionSequence, double quality) {
+      foreach (var t in stateActionSequence) {
+        var state = t.Item1;
+        var action = t.Item2;
+        QualityFunction.Update(state, action, quality);
+      }
+    }
+
+    protected override object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parent, int childIdx) {
+      return QualityFunction.StateFunction.CreateState(root, actions, parent, childIdx);
+    }
+
+    public override IDeepCloneable Clone(HeuristicLab.Common.Cloner cloner) {
+      return new UcbSymbolicExpressionConstructionPolicy(this, cloner);
+    }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Properties/AssemblyInfo.cs.frame	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/Properties/AssemblyInfo.cs.frame	(revision 12909)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Reflection;
+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.IteratedSymbolicExpressionConstruction")]
+[assembly: AssemblyDescription("Provides algorithms for optimization of symbolic expression tree problems.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2015 HEAL")]
+[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("630E3017-C668-49BC-8E91-8A06E06D3332")]
+
+// 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 Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.0.$WCREV$")]
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgQualityFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgQualityFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularAvgQualityFunction.cs	(revision 12909)
@@ -0,0 +1,90 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("TabularAvgQualityFunction", "")]
+  internal class TabularAvgQualityFunction : ParameterizedNamedItem, ITabularQualityFunction {
+    [Storable]
+    private readonly Dictionary<object, Dictionary<int, double>> q = new Dictionary<object, Dictionary<int, double>>();
+    [Storable]
+    private readonly Dictionary<object, Dictionary<int, int>> tries = new Dictionary<object, Dictionary<int, int>>();
+
+    public IStateFunction StateFunction {
+      get {
+        return ((IValueParameter<IStateFunction>)Parameters["State function"]).Value;
+      }
+      set { ((IValueParameter<IStateFunction>)Parameters["State function"]).Value = value; }
+    }
+
+    public TabularAvgQualityFunction() {
+      Parameters.Add(new ValueParameter<IStateFunction>("State function", "The function that is used to map partial trees to states", new DefaultStateFunction()));
+    }
+
+    public double Q(object state, int action) {
+      // an action that has never been tried has q == infinity
+      Dictionary<int, double> stateActionQualities;
+      if (!q.TryGetValue(state, out stateActionQualities)) return double.PositiveInfinity;
+      double quality;
+      if (!stateActionQualities.TryGetValue(action, out quality)) return double.PositiveInfinity;
+      return quality;
+    }
+
+    public void Update(object state, int action, double observedQuality) {
+      Dictionary<int, int> stateActionTries;
+      if (!tries.TryGetValue(state, out stateActionTries)) {
+        stateActionTries = new Dictionary<int, int>();
+        tries.Add(state, stateActionTries);
+      }
+      Dictionary<int, double> stateActionQualities = null;
+      if (!q.TryGetValue(state, out stateActionQualities)) {
+        stateActionQualities = new Dictionary<int, double>();
+        q.Add(state, stateActionQualities);
+      }
+      int t;
+      if (!stateActionTries.TryGetValue(action, out t)) {
+        t = 0;
+        stateActionTries.Add(action, t + 1);
+        stateActionQualities.Add(action, observedQuality);
+      } else {
+        stateActionTries[action] = t + 1;
+        var delta = observedQuality - stateActionQualities[action];
+        stateActionQualities[action] = stateActionQualities[action] + (1.0 / (t + 1)) * delta; // incremental calculation of average
+      }
+    }
+
+    public int Tries(object state, int action) {
+      Dictionary<int, int> stateTries;
+      if (!tries.TryGetValue(state, out stateTries)) return 0;
+      int stateActionTries;
+      if (!stateTries.TryGetValue(action, out stateActionTries)) return 0;
+      return stateActionTries;
+    }
+
+    #region item
+    [StorableConstructor]
+    protected TabularAvgQualityFunction(bool deserializing) : base(deserializing) { }
+    protected TabularAvgQualityFunction(TabularAvgQualityFunction original, Cloner cloner)
+      : base(original, cloner) {
+      this.q = new Dictionary<object, Dictionary<int, double>>(original.q);
+      this.tries = new Dictionary<object, Dictionary<int, int>>(original.tries);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TabularAvgQualityFunction(this, cloner);
+    }
+    #endregion
+
+    public void InitializeState() {
+      ClearState();
+    }
+
+    public void ClearState() {
+      q.Clear();
+      tries.Clear();
+    }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxQualityFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxQualityFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/QualityFunctions/TabularMaxQualityFunction.cs	(revision 12909)
@@ -0,0 +1,89 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  [StorableClass]
+  [Item("TabularMaxQualityFunction", "")]
+  internal class TabularMaxQualityFunction : ParameterizedNamedItem, ITabularQualityFunction {
+    [Storable]
+    private readonly Dictionary<object, Dictionary<int, double>> q = new Dictionary<object, Dictionary<int, double>>();
+    [Storable]
+    private readonly Dictionary<object, Dictionary<int, int>> tries = new Dictionary<object, Dictionary<int, int>>();
+
+    public IStateFunction StateFunction {
+      get {
+        return ((IValueParameter<IStateFunction>)Parameters["State function"]).Value;
+      }
+      set { ((IValueParameter<IStateFunction>)Parameters["State function"]).Value = value; }
+    }
+
+    public TabularMaxQualityFunction() {
+      Parameters.Add(new ValueParameter<IStateFunction>("State function", "The function that is used to map partial trees to states", new DefaultStateFunction()));
+    }
+
+    public double Q(object state, int action) {
+      // an action that has never been tried has q == infinity
+      Dictionary<int, double> stateActionQualities;
+      if (!q.TryGetValue(state, out stateActionQualities)) return double.PositiveInfinity;
+      double quality;
+      if (!stateActionQualities.TryGetValue(action, out quality)) return double.PositiveInfinity;
+      return quality;
+    }
+
+    public void Update(object state, int action, double observedQuality) {
+      Dictionary<int, int> stateActionTries;
+      if (!tries.TryGetValue(state, out stateActionTries)) {
+        stateActionTries = new Dictionary<int, int>();
+        tries.Add(state, stateActionTries);
+      }
+      Dictionary<int, double> stateActionQualities = null;
+      if (!q.TryGetValue(state, out stateActionQualities)) {
+        stateActionQualities = new Dictionary<int, double>();
+        q.Add(state, stateActionQualities);
+      }
+      int t;
+      if (!stateActionTries.TryGetValue(action, out t)) {
+        t = 0;
+        stateActionTries.Add(action, t + 1);
+        stateActionQualities.Add(action, observedQuality);
+      } else {
+        stateActionTries[action] = t + 1;
+        stateActionQualities[action] = Math.Max(stateActionQualities[action], observedQuality);
+      }
+    }
+
+    public int Tries(object state, int action) {
+      Dictionary<int, int> stateTries;
+      if (!tries.TryGetValue(state, out stateTries)) return 0;
+      int stateActionTries;
+      if (!stateTries.TryGetValue(action, out stateActionTries)) return 0;
+      return stateActionTries;
+    }
+
+    #region item
+    [StorableConstructor]
+    protected TabularMaxQualityFunction(bool deserializing) : base(deserializing) { }
+    protected TabularMaxQualityFunction(TabularMaxQualityFunction original, Cloner cloner)
+      : base(original, cloner) {
+      this.q = new Dictionary<object, Dictionary<int, double>>(original.q);
+      this.tries = new Dictionary<object, Dictionary<int, int>>(original.tries);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TabularMaxQualityFunction(this, cloner);
+    }
+    #endregion
+
+    public void InitializeState() {
+      ClearState();
+    }
+
+    public void ClearState() {
+      q.Clear();
+      tries.Clear();
+    }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/SearchTree.cs	(revision 12909)
@@ -0,0 +1,72 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Diagnostics.Contracts;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  internal class SearchTree {
+    private class Node {
+      internal Node parent;
+      internal Node[] children;
+      // children == null -> never visited
+      // children[i] != null -> visited at least once, still allowed
+      // children[i] = null -> fully explored
+    }
+
+    private Node root;
+
+    // for iteration
+    private Node currentNode;
+
+    public SearchTree() {
+      root = new Node();
+      currentNode = root;
+    }
+
+    public void ResetPosition() {
+      currentNode = root;
+    }
+
+    public bool IsLeafNode() {
+      return currentNode.children == null;
+    }
+
+    public void ExpandCurrentNode<T>(IEnumerable<T> actions) {
+      Contract.Assert(actions.Any());
+      Contract.Assert(currentNode.children == null);
+      currentNode.children = actions.Select(_ => new Node() { parent = currentNode }).ToArray();
+    }
+
+    public void Follow(int action) {
+      Contract.Assert(currentNode.children != null);
+      Contract.Assert(currentNode.children[action] != null);
+      currentNode = currentNode.children[action];
+    }
+
+    public IEnumerable<int> PossibleActions {
+      get {
+        return Enumerable.Range(0, currentNode.children.Length)
+                         .Where(i => currentNode.children[i] != null);
+      }
+    }
+
+    public void RemoveBranch(int action) {
+      Contract.Assert(currentNode.children != null);
+      Contract.Assert(currentNode.children[action] != null);
+      currentNode.children[action] = null;
+
+      RemoveRecursively(currentNode);
+    }
+
+    private void RemoveRecursively(Node node) {
+      if (node == null) return;
+      // when the last child has been removed we must remove the current node from it's parent
+      if (node.children.All(ch => ch == null) && node.parent != null) {
+        node.parent.children[Array.IndexOf(node.parent.children, node)] = null;
+        RemoveRecursively(node.parent);
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/DefaultStateFunction.cs	(revision 12909)
@@ -0,0 +1,36 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // simply returns the concatenated actions (the full path of actions to the current decision represents the state)
+  [StorableClass]
+  [Item("DefaultStateFunction", "")]
+  internal class DefaultStateFunction : Item, IStateFunction {
+    public DefaultStateFunction()
+      : base() {
+    }
+
+    public object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parentNode, int childIdx) {
+      return string.Join(",", actions);
+    }
+
+    #region item
+    [StorableConstructor]
+    protected DefaultStateFunction(bool deserializing) : base(deserializing) { }
+    protected DefaultStateFunction(DefaultStateFunction original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DefaultStateFunction(this, cloner);
+    }
+    #endregion
+
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction/3.3/StateFunctions/ParentChildStateFunction.cs	(revision 12909)
@@ -0,0 +1,36 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices.WindowsRuntime;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction {
+  // the state represents the combination of parent symbol and it's child index
+  [StorableClass]
+  [Item("ParentChildStateFunction", "")]
+  internal class ParentChildStateFunction : Item, IStateFunction {
+    public ParentChildStateFunction()
+      : base() {
+    }
+
+    public object CreateState(ISymbolicExpressionTreeNode root, List<int> actions, ISymbolicExpressionTreeNode parentNode, int childIdx) {
+      return (parentNode == null ? "" : parentNode.Symbol.Name) + childIdx;
+    }
+
+    #region item
+    [StorableConstructor]
+    protected ParentChildStateFunction(bool deserializing) : base(deserializing) { }
+    protected ParentChildStateFunction(ParentChildStateFunction original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParentChildStateFunction(this, cloner);
+    }
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/PreBuildEvent.cmd
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/PreBuildEvent.cmd	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/PreBuildEvent.cmd	(revision 12909)
@@ -0,0 +1,2 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
Index: /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Solution.sln
===================================================================
--- /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Solution.sln	(revision 12909)
+++ /branches/HeuristicLab.Algorithms.IteratedSentenceConstruction/Solution.sln	(revision 12909)
@@ -0,0 +1,41 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{07ACD823-D867-4F33-8C0A-EA80A0996100}"
+	ProjectSection(SolutionItems) = preProject
+		Build.cmd = Build.cmd
+		PreBuildEvent.cmd = PreBuildEvent.cmd
+	EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3", "HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction\3.3\HeuristicLab.Algorithms.IteratedSymbolicExpressionConstruction-3.3.csproj", "{9D804CEF-4827-404F-834D-68540FA26551}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|x64.ActiveCfg = Debug|x64
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|x64.Build.0 = Debug|x64
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|x86.ActiveCfg = Debug|x86
+		{9D804CEF-4827-404F-834D-68540FA26551}.Debug|x86.Build.0 = Debug|x86
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|x64.ActiveCfg = Release|x64
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|x64.Build.0 = Release|x64
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|x86.ActiveCfg = Release|x86
+		{9D804CEF-4827-404F-834D-68540FA26551}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(Performance) = preSolution
+		HasPerformanceSessions = true
+	EndGlobalSection
+EndGlobal
