Index: /trunk/sources/HeuristicLab.GP.Operators/3.3/Initialization/ProbabilisticTreeCreator.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Operators/3.3/Initialization/ProbabilisticTreeCreator.cs	(revision 2446)
+++ /trunk/sources/HeuristicLab.GP.Operators/3.3/Initialization/ProbabilisticTreeCreator.cs	(revision 2447)
@@ -27,5 +27,5 @@
 namespace HeuristicLab.GP.Operators {
   public class ProbabilisticTreeCreator : OperatorBase {
-    private int MAX_TRIES { get { return 100; } }
+    private static int MAX_TRIES { get { return 100; } }
 
     public override string Description {
@@ -50,21 +50,25 @@
       int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
 
-      int treeSize = random.Next(minTreeSize, maxTreeSize + 1);
-      IFunctionTree root;
-      int tries = 0;
-      TreeGardener gardener = new TreeGardener(random, funLibrary);
-      do {
-        root = gardener.PTC2(treeSize, maxTreeHeight);
-        if (tries++ >= MAX_TRIES) {
-          // try a different size
-          treeSize = random.Next(minTreeSize, maxTreeSize + 1);
-          tries = 0;
-        }
-      } while (root.GetSize() > maxTreeSize || root.GetHeight() > maxTreeHeight);
-
+      IFunctionTree root = Create(random, funLibrary, minTreeSize, maxTreeSize, maxTreeHeight);
       scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), new GeneticProgrammingModel(root)));
       return Util.CreateInitializationOperation(TreeGardener.GetAllSubTrees(root), scope);
     }
 
- }
+
+    public static IFunctionTree Create(IRandom random, FunctionLibrary funLib, int minSize, int maxSize, int maxHeight) {
+      int treeSize = random.Next(minSize, maxSize + 1);
+      IFunctionTree root;
+      int tries = 0;
+      TreeGardener gardener = new TreeGardener(random, funLib);
+      do {
+        root = gardener.PTC2(treeSize, maxHeight);
+        if (tries++ >= MAX_TRIES) {
+          // try a different size
+          treeSize = random.Next(minSize, maxSize + 1);
+          tries = 0;
+        }
+      } while (root.GetSize() > maxHeight || root.GetHeight() > maxHeight);
+      return root;
+    }
+  }
 }
Index: /trunk/sources/HeuristicLab.GP.Tests/HL3TreeEvaluatorTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/HL3TreeEvaluatorTest.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/HL3TreeEvaluatorTest.cs	(revision 2447)
@@ -0,0 +1,247 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.GP.StructureIdentification;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.GP.Interfaces;
+using System.IO;
+using HeuristicLab.DataAnalysis;
+using System;
+using HeuristicLab.Random;
+using System.Collections.Generic;
+using HeuristicLab.GP.Operators;
+using System.Diagnostics;
+namespace HeuristicLab.GP.Test {
+
+
+  /// <summary>
+  ///This is a test class for HL3TreeEvaluatorTest and is intended
+  ///to contain all HL3TreeEvaluatorTest Unit Tests
+  ///</summary>
+  [TestClass()]
+  public class HL3TreeEvaluatorTest {
+    private const int N = 1000;
+    private const int Rows = 1000;
+    private const int Columns = 50;
+    private static IFunctionTree[] randomTrees;
+    private static Dataset dataset;
+    private static MersenneTwister twister;
+    private TestContext testContextInstance;
+
+    /// <summary>
+    ///Gets or sets the test context which provides
+    ///information about and functionality for the current test run.
+    ///</summary>
+    public TestContext TestContext {
+      get {
+        return testContextInstance;
+      }
+      set {
+        testContextInstance = value;
+      }
+    }
+
+    [ClassInitialize()]
+    public static void CreateRandomTrees(TestContext testContext) {
+      twister = new MersenneTwister();
+      dataset = Util.CreateRandomDataset(twister, Rows, Columns);
+      randomTrees = Util.CreateRandomTrees(twister, dataset, N, 1, 100);
+    }
+
+
+    [TestMethod()]
+    public void PerformanceTest() {
+      double[] estimation = new double[Rows];
+      foreach (IFunctionTree tree in randomTrees) {
+        Util.InitTree(tree, twister, new List<string>(dataset.VariableNames));
+      }
+      HL3TreeEvaluator hl3TreeEvaluator = new HL3TreeEvaluator();
+      Util.EvaluateTrees(randomTrees, hl3TreeEvaluator, dataset, 10);
+    }
+
+
+    /// <summary>
+    ///A test for Evaluate
+    ///</summary>
+    [TestMethod()]
+    [DeploymentItem("HeuristicLab.GP.StructureIdentification-3.3.dll")]
+    public void HL3TreeEvaluatorEvaluateTest() {
+
+      Dataset ds = new Dataset(new double[,] {
+        { 1.0, 1.0, 1.0 },
+        { 2.0, 2.0, 2.0 },
+        { 3.0, 1.0, 2.0 }
+      });
+
+      ds.SetVariableName(0, "y");
+      ds.SetVariableName(1, "a");
+      ds.SetVariableName(2, "b");
+
+      HL3TreeEvaluator evaluator = new HL3TreeEvaluator();
+
+      // constants
+      Evaluate(evaluator, ds, "(+ 1,5 3,5)", 0, 5.0);
+
+      // variables
+      Evaluate(evaluator, ds, "(variable 2,0 a 0)", 0, 2.0);
+      Evaluate(evaluator, ds, "(variable 2,0 a 0)", 1, 4.0);
+      Evaluate(evaluator, ds, "(variable 2,0 a -1)", 1, 2.0);
+      Evaluate(evaluator, ds, "(variable 2,0 a -2)", 2, 2.0);
+
+      // differentials
+      Evaluate(evaluator, ds, "(differential 2,0 a 0)", 1, 2.0);
+      Evaluate(evaluator, ds, "(differential 2,0 a 0)", 2, -2.0);
+      Evaluate(evaluator, ds, "(differential 2,0 a -1)", 2, 2.0);
+      Evaluate(evaluator, ds, "(differential 2,0 a -2)", 3, 2.0);
+
+      // addition
+      Evaluate(evaluator, ds, "(+ (variable 2,0 a 0))", 1, 4.0);
+      Evaluate(evaluator, ds, "(+ (variable 2,0 a 0) (variable 3,0 b 0))", 0, 5.0);
+      Evaluate(evaluator, ds, "(+ (variable 2,0 a 0) (variable 3,0 b 0))", 1, 10.0);
+      Evaluate(evaluator, ds, "(+ (variable 2,0 a 0) (variable 3,0 b 0))", 2, 8.0);
+      Evaluate(evaluator, ds, "(+ 8,0 2,0 2,0)", 0, 12.0);
+
+      // subtraction
+      Evaluate(evaluator, ds, "(- (variable 2,0 a 0))", 1, -4.0);
+      Evaluate(evaluator, ds, "(- (variable 2,0 a 0) (variable 3,0 b 0))", 0, -1.0);
+      Evaluate(evaluator, ds, "(- (variable 2,0 a 0) (variable 3,0 b 0))", 1, -2.0);
+      Evaluate(evaluator, ds, "(- (variable 2,0 a 0) (variable 3,0 b 0))", 2, -4.0);
+      Evaluate(evaluator, ds, "(- 8,0 2,0 2,0)", 0, 4.0);
+
+      // multiplication
+      Evaluate(evaluator, ds, "(* (variable 2,0 a 0))", 0, 2.0);
+      Evaluate(evaluator, ds, "(* (variable 2,0 a 0) (variable 3,0 b 0))", 0, 6.0);
+      Evaluate(evaluator, ds, "(* (variable 2,0 a 0) (variable 3,0 b 0))", 1, 24.0);
+      Evaluate(evaluator, ds, "(* (variable 2,0 a 0) (variable 3,0 b 0))", 2, 12.0);
+      Evaluate(evaluator, ds, "(* 8,0 2,0 2,0)", 0, 32.0);
+
+      // division
+      Evaluate(evaluator, ds, "(/ (variable 2,0 a 0))", 1, 1.0 / 4.0);
+      Evaluate(evaluator, ds, "(/ (variable 2,0 a 0) 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(/ (variable 2,0 a 0) 2,0)", 1, 2.0);
+      Evaluate(evaluator, ds, "(/ (variable 3,0 b 0) 2,0)", 2, 3.0);
+      Evaluate(evaluator, ds, "(/ 8,0 2,0 2,0)", 0, 2.0);
+
+      // boolean values semantic: false = x <= 0 , true x > 0
+      // equ
+      Evaluate(evaluator, ds, "(equ (variable 2,0 a 0) 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(equ (variable 2,0 a 0) 1,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(equ (sqrt -1,0) (log -1,0))", 0, -1.0); // (equ nan nan) should be false
+
+
+      // gt
+      Evaluate(evaluator, ds, "(> (variable 2,0 a 0) 2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(> 2,0 (variable 2,0 a 0))", 0, -1.0);
+      Evaluate(evaluator, ds, "(> (variable 2,0 a 0) 1,9)", 0, 1.0);
+      Evaluate(evaluator, ds, "(> 1,9 (variable 2,0 a 0))", 0, -1.0);
+      Evaluate(evaluator, ds, "(> (sqrt -1,0) (log -1,0))", 0, -1.0); // (> nan nan) should be false
+
+      // lt
+      Evaluate(evaluator, ds, "(< (variable 2,0 a 0) 2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(< 2,0 (variable 2,0 a 0))", 0, -1.0);
+      Evaluate(evaluator, ds, "(< (variable 2,0 a 0) 1,9)", 0, -1.0);
+      Evaluate(evaluator, ds, "(< 1,9 (variable 2,0 a 0))", 0, 1.0);
+      Evaluate(evaluator, ds, "(< (sqrt -1,0) (log -1,0))", 0, -1.0); // (< nan nan) should be false
+
+      // If
+      Evaluate(evaluator, ds, "(if -10 2,0 3,0)", 0, 3.0);
+      Evaluate(evaluator, ds, "(if -1,0 2,0 3,0)", 0, 3.0);
+      Evaluate(evaluator, ds, "(if 0,0 2,0 3,0)", 0, 3.0);
+      Evaluate(evaluator, ds, "(if 1,0 2,0 3,0)", 0, 2.0);
+      Evaluate(evaluator, ds, "(if 10 2,0 3,0)", 0, 2.0);
+      Evaluate(evaluator, ds, "(if (sqrt -1,0) 2,0 3,0)", 0, 3.0); // if(nan) should return the else branch
+
+      // signum
+      Evaluate(evaluator, ds, "(sign -1,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(sign -2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(sign 1,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(sign 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(sign 0,0)", 0, 0.0);
+
+      // NOT
+      Evaluate(evaluator, ds, "(not -1,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(not -2,0)", 0, 2.0);
+      Evaluate(evaluator, ds, "(not 1,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(not 2,0)", 0, -2.0);
+      Evaluate(evaluator, ds, "(not 0,0)", 0, 0.0);
+
+      // AND
+      Evaluate(evaluator, ds, "(and -1,0 -2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(and -1,0 2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(and 1,0 -2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(and 1,0 0,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(and 0,0 0,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(and 1,0 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(and 1,0 2,0 3,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(and 1,0 -2,0 3,0)", 0, -1.0);
+
+      // OR
+      Evaluate(evaluator, ds, "(or -1,0 -2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(or -1,0 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(or 1,0 -2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(or 1,0 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(or 0,0 0,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(or -1,0 -2,0 -3,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(or -1,0 -2,0 3,0)", 0, 1.0);
+
+      // XOR
+      Evaluate(evaluator, ds, "(xor -1,0 -2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(xor -1,0 2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(xor 1,0 -2,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(xor 1,0 2,0)", 0, -1.0);
+      Evaluate(evaluator, ds, "(xor 0,0 0,0)", 0, -1.0);
+
+      // sin, cos, tan
+      Evaluate(evaluator, ds, "(sin " + Math.PI + ")", 0, 0.0);
+      Evaluate(evaluator, ds, "(sin 0,0)", 0, 0.0);
+      Evaluate(evaluator, ds, "(cos " + Math.PI + ")", 0, -1.0);
+      Evaluate(evaluator, ds, "(cos 0,0)", 0, 1.0);
+      Evaluate(evaluator, ds, "(tan " + Math.PI + ")", 0, Math.Tan(Math.PI));
+      Evaluate(evaluator, ds, "(tan 0,0)", 0, Math.Tan(Math.PI));
+
+
+      // expt
+      Evaluate(evaluator, ds, "(expt 2,0 2,0)", 0, 4.0);
+      Evaluate(evaluator, ds, "(expt 2,0 3,0)", 0, 8.0);
+      Evaluate(evaluator, ds, "(expt 3,0 2,0)", 0, 9.0);
+
+      // exp, log
+      Evaluate(evaluator, ds, "(log (exp 7,0))", 0, Math.Log(Math.Exp(7)));
+      Evaluate(evaluator, ds, "(exp (log 7,0))", 0, Math.Exp(Math.Log(7)));
+      Evaluate(evaluator, ds, "(log -3,0)", 0, Math.Log(-3));
+
+      // sqrt
+      Evaluate(evaluator, ds, "(sqrt 4,0)", 0, 2.0);
+      Evaluate(evaluator, ds, "(sqrt (sqrt 16,0))", 0, 2.0);
+
+    }
+
+    private void Evaluate(HL3TreeEvaluator evaluator, Dataset ds, string expr, int index, double expected) {
+      var importer = new SymbolicExpressionImporter();
+      IFunctionTree tree = importer.Import(expr);
+
+      evaluator.PrepareForEvaluation(ds, tree);
+
+      double actual = evaluator.Evaluate(index);
+      Assert.AreEqual(expected, actual, 1.0E-12, expr);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/HeuristicLab.GP.Tests.csproj	(revision 2447)
@@ -0,0 +1,114 @@
+﻿<Project ToolsVersion="3.5" 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>{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.Tests</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.Tests</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+  </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>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="HL3TreeEvaluatorTest.cs" />
+    <Compile Include="ProbabilisticTreeCreatorTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="SymbolicExpressionImporter.cs" />
+    <Compile Include="Token.cs" />
+    <Compile Include="Util.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Core\3.2\HeuristicLab.Core-3.2.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\3.2\HeuristicLab.DataAnalysis-3.2.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis-3.2</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.Interfaces\3.3\HeuristicLab.GP.Interfaces-3.3.csproj">
+      <Project>{924B6BEA-9A99-40FE-9334-5C01E8D540EC}</Project>
+      <Name>HeuristicLab.GP.Interfaces-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.Operators\3.3\HeuristicLab.GP.Operators-3.3.csproj">
+      <Project>{45D11FBD-A71B-48D3-8A94-8EB0DFE8E06A}</Project>
+      <Name>HeuristicLab.GP.Operators-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification.Classification\3.3\HeuristicLab.GP.StructureIdentification.Classification-3.3.csproj">
+      <Project>{7C20D100-8BEB-433A-9499-F075E2CB9297}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification.Classification-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification.ConditionalEvaluation\3.3\HeuristicLab.GP.StructureIdentification.ConditionalEvaluation-3.3.csproj">
+      <Project>{ABAE70E0-14E3-4588-B6BB-15DF022985C3}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification.ConditionalEvaluation-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification.TimeSeries\3.3\HeuristicLab.GP.StructureIdentification.TimeSeries-3.3.csproj">
+      <Project>{6084CFB5-733F-449D-9F92-2E40D13F0514}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification.TimeSeries-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\3.3\HeuristicLab.GP.StructureIdentification-3.3.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\3.3\HeuristicLab.GP-3.3.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Random\3.2\HeuristicLab.Random-3.2.csproj">
+      <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
+      <Name>HeuristicLab.Random-3.2</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\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: /trunk/sources/HeuristicLab.GP.Tests/ProbabilisticTreeCreatorTest.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/ProbabilisticTreeCreatorTest.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/ProbabilisticTreeCreatorTest.cs	(revision 2447)
@@ -0,0 +1,117 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.GP.StructureIdentification;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.DataAnalysis;
+using System;
+using HeuristicLab.GP.Interfaces;
+using HeuristicLab.Random;
+using HeuristicLab.GP.Operators;
+using System.Collections.Generic;
+using System.Text;
+namespace HeuristicLab.GP.Test {
+
+
+  [TestClass()]
+  public class ProbabilisticTreeCreatorTest {
+    private const int N = 1000;
+    private TestContext testContextInstance;
+    private static IFunctionTree[] randomTrees;
+
+    /// <summary>
+    ///Gets or sets the test context which provides
+    ///information about and functionality for the current test run.
+    ///</summary>
+    public TestContext TestContext {
+      get {
+        return testContextInstance;
+      }
+      set {
+        testContextInstance = value;
+      }
+    }
+
+    [ClassInitialize()]
+    public static void CreateRandomTrees(TestContext testContext) {
+      MersenneTwister twister = new MersenneTwister();
+      Dataset ds = Util.CreateRandomDataset(twister, 1, 20);
+      randomTrees = Util.CreateRandomTrees(twister, ds, N, 1, 100);
+    }
+
+    [TestMethod()]
+    public void SizeDistributionTest() {
+      int[] histogram = new int[105 / 5];
+      for (int i = 0; i < randomTrees.Length; i++) {
+        histogram[randomTrees[i].GetSize() / 5]++;
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      for (int i = 0; i < histogram.Length; i++) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append("< "); strBuilder.Append((i + 1) * 5);
+        strBuilder.Append(": "); strBuilder.Append(histogram[i]);
+      }
+      Assert.Inconclusive("Size distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+
+    [TestMethod()]
+    public void FunctionDistributionTest() {
+      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
+      for (int i = 0; i < randomTrees.Length; i++) {
+        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
+          if (node.SubTrees.Count > 0) {
+            if (!occurances.ContainsKey(node.Function))
+              occurances[node.Function] = 0;
+            occurances[node.Function]++;
+          }
+        }
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      foreach (var function in occurances.Keys) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append(function.Name); strBuilder.Append(": ");
+        strBuilder.Append(occurances[function]);
+      }
+      Assert.Inconclusive("Function distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+
+    [TestMethod()]
+    public void TerminalDistributionTest() {
+      Dictionary<IFunction, int> occurances = new Dictionary<IFunction, int>();
+      for (int i = 0; i < randomTrees.Length; i++) {
+        foreach (var node in FunctionTreeIterator.IteratePrefix(randomTrees[i])) {
+          if (node.SubTrees.Count == 0) {
+            if (!occurances.ContainsKey(node.Function))
+              occurances[node.Function] = 0;
+            occurances[node.Function]++;
+          }
+        }
+      }
+      StringBuilder strBuilder = new StringBuilder();
+      foreach (var function in occurances.Keys) {
+        strBuilder.Append(Environment.NewLine);
+        strBuilder.Append(function.Name); strBuilder.Append(": ");
+        strBuilder.Append(occurances[function]);
+      }
+      Assert.Inconclusive("Terminal distribution of ProbabilisticTreeCreator: " + strBuilder);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.GP.Tests/Properties/AssemblyInfo.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/Properties/AssemblyInfo.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/Properties/AssemblyInfo.cs	(revision 2447)
@@ -0,0 +1,35 @@
+﻿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.GP.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab.GP.Tests")]
+[assembly: AssemblyCopyright("Copyright ©  2009")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM componenets.  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("5b2a39d0-9d96-427c-b6a6-94d9dcf3f53e")]
+
+// 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("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
Index: /trunk/sources/HeuristicLab.GP.Tests/SymbolicExpressionImporter.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/SymbolicExpressionImporter.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/SymbolicExpressionImporter.cs	(revision 2447)
@@ -0,0 +1,133 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.GP.Interfaces;
+using System.IO;
+using System.Diagnostics;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Test {
+  class SymbolicExpressionImporter {
+    private const string DIFFSTART = "dif";
+    private const string VARSTART = "var";
+    private Dictionary<string, IFunction> knownFunctions = new Dictionary<string, IFunction>() 
+      {
+        {"+", new Addition()},
+        {"and", new And()},
+        {"mean", new Average()},
+        {"cos", new Cosinus()},
+        {"/", new Division()},
+        {"equ", new Equal()},
+        {"exp", new Exponential()},
+        {">", new GreaterThan()},
+        {"if", new IfThenElse()},
+        {"<", new LessThan()},
+        {"log", new Logarithm()},
+        {"*", new Multiplication()},
+        {"not", new Not()},
+        {"or", new Or()},
+        {"expt", new Power()},
+        {"sign", new Signum()},
+        {"sin",new Sinus()},
+        {"sqrt", new Sqrt()},
+        {"-", new Subtraction()},
+        {"tan", new Tangens()},
+        {"xor", new Xor()}
+      };
+    Constant constant = new Constant();
+    HeuristicLab.GP.StructureIdentification.Variable variable = new HeuristicLab.GP.StructureIdentification.Variable();
+    Differential differential = new Differential();
+
+    public SymbolicExpressionImporter() {
+    }
+
+    internal IFunctionTree Import(string str) {
+      str = str.Replace("(", " ( ").Replace(")", " ) ");
+      return ParseSexp(new Queue<Token>(GetTokenStream(str)));
+    }
+
+    private IEnumerable<Token> GetTokenStream(string str) {
+      return
+             from strToken in str.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).AsEnumerable()
+             let t = Token.Parse(strToken)
+             where t != null
+             select t;
+    }
+
+    private HeuristicLab.GP.Interfaces.IFunctionTree ParseSexp(Queue<Token> tokens) {
+      if (tokens.Peek().Symbol == TokenSymbol.LPAR) {
+        IFunctionTree tree;
+        Expect(Token.LPAR, tokens);
+        if (tokens.Peek().StringValue.StartsWith(VARSTART)) {
+          tree = ParseVariable(tokens);
+        } else if (tokens.Peek().StringValue.StartsWith(DIFFSTART)) {
+          tree = ParseDifferential(tokens);
+        } else {
+          Token curToken = tokens.Dequeue();
+          tree = CreateTree(curToken);
+          while (!tokens.Peek().Equals(Token.RPAR)) {
+            tree.AddSubTree(ParseSexp(tokens));
+          }
+        }
+        Expect(Token.RPAR, tokens);
+        return tree;
+      } else if (tokens.Peek().Symbol == TokenSymbol.NUMBER) {
+        ConstantFunctionTree t = (ConstantFunctionTree)constant.GetTreeNode();
+        t.Value = tokens.Dequeue().DoubleValue;
+        return t;
+      } else throw new FormatException("Expected function or constant symbol");
+    }
+
+    private IFunctionTree ParseDifferential(Queue<Token> tokens) {
+      Token diffTok = tokens.Dequeue();
+      Debug.Assert(diffTok.StringValue == "differential");
+      VariableFunctionTree t = (VariableFunctionTree)differential.GetTreeNode();
+      t.Weight = tokens.Dequeue().DoubleValue;
+      t.VariableName = tokens.Dequeue().StringValue;
+      t.SampleOffset = (int)tokens.Dequeue().DoubleValue;
+      return t;
+    }
+
+    private IFunctionTree ParseVariable(Queue<Token> tokens) {
+      Token varTok = tokens.Dequeue();
+      Debug.Assert(varTok.StringValue == "variable");
+      VariableFunctionTree t = (VariableFunctionTree)variable.GetTreeNode();
+      t.Weight = tokens.Dequeue().DoubleValue;
+      t.VariableName = tokens.Dequeue().StringValue;
+      t.SampleOffset = (int)tokens.Dequeue().DoubleValue;
+      return t;
+    }
+
+    private IFunctionTree CreateTree(Token token) {
+      if (token.Symbol != TokenSymbol.SYMB) throw new FormatException("Expected function symbol, but got: " + token.StringValue);
+      return knownFunctions[token.StringValue].GetTreeNode();
+    }
+
+    private void Expect(Token token, Queue<Token> tokens) {
+      Token cur = tokens.Dequeue();
+      if (!token.Equals(cur)) throw new FormatException("Expected: " + token.StringValue + ", but got found: " + cur.StringValue);
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.GP.Tests/Token.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/Token.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/Token.cs	(revision 2447)
@@ -0,0 +1,70 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using HeuristicLab.GP;
+using HeuristicLab.GP.Interfaces;
+using HeuristicLab.GP.StructureIdentification;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP.Test {
+  public enum TokenSymbol { LPAR, RPAR, SYMB, NUMBER };
+  public class Token {
+    public static readonly Token LPAR = Token.Parse("(");
+    public static readonly Token RPAR = Token.Parse(")");
+
+    public TokenSymbol Symbol { get; set; }
+    public string StringValue { get; set; }
+    public double DoubleValue { get; set; }
+    public Token() { }
+
+    public override bool Equals(object obj) {
+      Token other = (obj as Token);
+      if (other == null) return false;
+      if (other.Symbol != Symbol) return false;
+      return other.StringValue == this.StringValue;
+    }
+
+    public static Token Parse(string strToken) {
+      strToken = strToken.Trim();
+      Token t = new Token();
+      t.StringValue = strToken.Trim();
+      double temp;
+      if (strToken == "") {
+        t = null;
+      } else if (strToken == "(") {
+        t.Symbol = TokenSymbol.LPAR;
+      } else if (strToken == ")") {
+        t.Symbol = TokenSymbol.RPAR;
+      } else if (double.TryParse(strToken, out temp)) {
+        t.Symbol = TokenSymbol.NUMBER;
+        t.DoubleValue = double.Parse(strToken);
+      } else {
+        t.Symbol = TokenSymbol.SYMB;
+      }
+      return t;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.GP.Tests/Util.cs
===================================================================
--- /trunk/sources/HeuristicLab.GP.Tests/Util.cs	(revision 2447)
+++ /trunk/sources/HeuristicLab.GP.Tests/Util.cs	(revision 2447)
@@ -0,0 +1,235 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.GP.StructureIdentification;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using HeuristicLab.DataAnalysis;
+using System;
+using HeuristicLab.GP.Interfaces;
+using HeuristicLab.Random;
+using HeuristicLab.GP.Operators;
+using System.Collections.Generic;
+using System.Text;
+using System.Diagnostics;
+namespace HeuristicLab.GP.Test {
+  public class Util {
+
+    public static void InitTree(IFunctionTree tree, MersenneTwister twister, List<string> varNames) {
+      foreach (var node in FunctionTreeIterator.IteratePostfix(tree)) {
+        if (node is VariableFunctionTree) {
+          var varNode = node as VariableFunctionTree;
+          varNode.Weight = twister.NextDouble() * 20.0 - 10.0;
+          varNode.SampleOffset = 0;
+          varNode.VariableName = varNames[twister.Next(varNames.Count)];
+        } else if (node is ConstantFunctionTree) {
+          var constantNode = node as ConstantFunctionTree;
+          constantNode.Value = twister.NextDouble() * 20.0 - 10.0;
+        }
+      }
+    }
+
+    public static FunctionLibrary CreateFunctionLibrary() {
+      FunctionLibrary functionLibrary = new FunctionLibrary();
+
+      Variable variable = new Variable();
+      Constant constant = new Constant();
+      Differential differential = new Differential();
+      Addition addition = new Addition();
+      And and = new And();
+      //Average average = new Average();
+      Cosinus cosinus = new Cosinus();
+      Division division = new Division();
+      Equal equal = new Equal();
+      Exponential exponential = new Exponential();
+      GreaterThan greaterThan = new GreaterThan();
+      IfThenElse ifThenElse = new IfThenElse();
+      LessThan lessThan = new LessThan();
+      Logarithm logarithm = new Logarithm();
+      Multiplication multiplication = new Multiplication();
+      Not not = new Not();
+      Or or = new Or();
+      Power power = new Power();
+      Signum signum = new Signum();
+      Sinus sinus = new Sinus();
+      Sqrt sqrt = new Sqrt();
+      Subtraction subtraction = new Subtraction();
+      Tangens tangens = new Tangens();
+      Xor xor = new Xor();
+
+
+      List<IFunction> booleanFunctions = new List<IFunction>();
+      booleanFunctions.Add(and);
+      booleanFunctions.Add(equal);
+      booleanFunctions.Add(greaterThan);
+      booleanFunctions.Add(lessThan);
+      booleanFunctions.Add(not);
+      booleanFunctions.Add(or);
+      booleanFunctions.Add(xor);
+
+      List<IFunction> doubleFunctions = new List<IFunction>();
+      doubleFunctions.Add(differential);
+      doubleFunctions.Add(variable);
+      doubleFunctions.Add(constant);
+      doubleFunctions.Add(addition);
+      //doubleFunctions.Add(average);
+      doubleFunctions.Add(cosinus);
+      doubleFunctions.Add(division);
+      doubleFunctions.Add(exponential);
+      doubleFunctions.Add(ifThenElse);
+      doubleFunctions.Add(logarithm);
+      doubleFunctions.Add(multiplication);
+      doubleFunctions.Add(power);
+      doubleFunctions.Add(signum);
+      doubleFunctions.Add(sinus);
+      doubleFunctions.Add(sqrt);
+      doubleFunctions.Add(subtraction);
+      doubleFunctions.Add(tangens);
+
+      SetAllowedSubOperators(and, booleanFunctions);
+      SetAllowedSubOperators(equal, doubleFunctions);
+      SetAllowedSubOperators(greaterThan, doubleFunctions);
+      SetAllowedSubOperators(lessThan, doubleFunctions);
+      SetAllowedSubOperators(not, booleanFunctions);
+      SetAllowedSubOperators(or, booleanFunctions);
+      SetAllowedSubOperators(xor, booleanFunctions);
+      SetAllowedSubOperators(addition, doubleFunctions);
+      //SetAllowedSubOperators(average, doubleFunctions);
+      SetAllowedSubOperators(cosinus, doubleFunctions);
+      SetAllowedSubOperators(division, doubleFunctions);
+      SetAllowedSubOperators(exponential, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 0, booleanFunctions);
+      SetAllowedSubOperators(ifThenElse, 1, doubleFunctions);
+      SetAllowedSubOperators(ifThenElse, 2, doubleFunctions);
+      SetAllowedSubOperators(logarithm, doubleFunctions);
+      SetAllowedSubOperators(multiplication, doubleFunctions);
+      SetAllowedSubOperators(power, doubleFunctions);
+      SetAllowedSubOperators(signum, doubleFunctions);
+      SetAllowedSubOperators(sinus, doubleFunctions);
+      SetAllowedSubOperators(sqrt, doubleFunctions);
+      SetAllowedSubOperators(subtraction, doubleFunctions);
+      SetAllowedSubOperators(tangens, doubleFunctions);
+
+      functionLibrary.AddFunction(differential);
+      functionLibrary.AddFunction(variable);
+      functionLibrary.AddFunction(constant);
+      functionLibrary.AddFunction(addition);
+      //functionLibrary.AddFunction(average);
+      functionLibrary.AddFunction(and);
+      functionLibrary.AddFunction(cosinus);
+      functionLibrary.AddFunction(division);
+      functionLibrary.AddFunction(equal);
+      functionLibrary.AddFunction(exponential);
+      functionLibrary.AddFunction(greaterThan);
+      functionLibrary.AddFunction(ifThenElse);
+      functionLibrary.AddFunction(lessThan);
+      functionLibrary.AddFunction(logarithm);
+      functionLibrary.AddFunction(multiplication);
+      functionLibrary.AddFunction(not);
+      functionLibrary.AddFunction(power);
+      functionLibrary.AddFunction(or);
+      functionLibrary.AddFunction(signum);
+      functionLibrary.AddFunction(sinus);
+      functionLibrary.AddFunction(sqrt);
+      functionLibrary.AddFunction(subtraction);
+      functionLibrary.AddFunction(tangens);
+      functionLibrary.AddFunction(xor);
+
+      variable.SetConstraints(0, 0);
+      differential.SetConstraints(0, 0);
+
+      return functionLibrary;
+
+    }
+
+    private static void SetAllowedSubOperators(IFunction f, IEnumerable<IFunction> gs) {
+      for (int i = 0; i < f.MaxSubTrees; i++) {
+        SetAllowedSubOperators(f, i, gs);
+      }
+    }
+
+    private static void SetAllowedSubOperators(IFunction f, int i, IEnumerable<IFunction> gs) {
+      foreach (var g in gs) {
+        f.AddAllowedSubFunction(g, i);
+      }
+    }
+
+    public static IFunctionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, int popSize) {
+      return CreateRandomTrees(twister, dataset, popSize, 1, 200);
+    }
+
+    public static IFunctionTree[] CreateRandomTrees(MersenneTwister twister, Dataset dataset, int popSize, int minSize, int maxSize) {
+      IFunctionTree[] randomTrees = new IFunctionTree[popSize];
+      FunctionLibrary funLib = Util.CreateFunctionLibrary();
+      for (int i = 0; i < randomTrees.Length; i++) {
+        randomTrees[i] = ProbabilisticTreeCreator.Create(twister, funLib, minSize, maxSize, maxSize + 1);
+      }
+      return randomTrees;
+    }
+
+
+    public static Dataset CreateRandomDataset(MersenneTwister twister, int rows, int columns) {
+      double[,] data = new double[rows, columns];
+      for (int i = 0; i < rows; i++) {
+        for (int j = 0; j < columns; j++) {
+          data[i, j] = twister.NextDouble() * 2.0 - 1.0;
+        }
+      }
+      Dataset ds = new Dataset(data);
+      ds.SetVariableName(0, "y");
+      return ds;
+    }
+
+    public static double NodesPerSecond(long nNodes, Stopwatch watch) {
+      return nNodes / (watch.ElapsedMilliseconds / 1000.0);
+    }
+
+    public static void EvaluateTrees(IFunctionTree[] trees, ITreeEvaluator evaluator, Dataset dataset, int repetitions) {
+      double[] estimation = new double[dataset.Rows];
+      // warm up
+      for (int i = 0; i < trees.Length; i++) {
+        evaluator.PrepareForEvaluation(dataset, trees[i]);
+        for (int row = 1; row < dataset.Rows; row++) {
+          estimation[row] = evaluator.Evaluate(row);
+        }
+      }
+
+      Stopwatch watch = new Stopwatch();
+      Stopwatch compileWatch = new Stopwatch();
+      long nNodes = 0;
+      for (int rep = 0; rep < repetitions; rep++) {
+        watch.Start();
+        for (int i = 0; i < trees.Length; i++) {
+          compileWatch.Start();
+          evaluator.PrepareForEvaluation(dataset, trees[i]);
+          nNodes += trees[i].GetSize() * (dataset.Rows - 1);
+          compileWatch.Stop();
+          for (int row = 1; row < dataset.Rows; row++) {
+            estimation[row] = evaluator.Evaluate(row);
+          }
+        }
+        watch.Stop();
+      }
+      Assert.Inconclusive("Random tree evaluation performance of " + evaluator.GetType() + ":" +
+        watch.ElapsedMilliseconds + "ms (" + compileWatch.ElapsedMilliseconds + " ms) " +
+        Util.NodesPerSecond(nNodes, watch) + " nodes/sec");
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.sln
===================================================================
--- /trunk/sources/HeuristicLab.sln	(revision 2446)
+++ /trunk/sources/HeuristicLab.sln	(revision 2447)
@@ -252,5 +252,5 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ALGLIB", "ALGLIB\ALGLIB.csproj", "{44456535-5DB5-454A-BE2B-7426DA6700B6}"
 EndProject
-Global
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP.Tests", "HeuristicLab.GP.Tests\HeuristicLab.GP.Tests.csproj", "{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}"EndProjectGlobal
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		CEDMA Debug|Any CPU = CEDMA Debug|Any CPU
@@ -4013,6 +4013,6 @@
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU
-		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Modeling Debug|x86.ActiveCfg = Debug|Any CPU
-		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Modeling Debug|x86.ActiveCfg = Debug|x86
+		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Modeling Debug|x86.Build.0 = Debug|x86		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Release|Any CPU.Build.0 = Release|Any CPU
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Release|x64.ActiveCfg = Release|x64
@@ -4028,5 +4028,5 @@
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU
 		{44456535-5DB5-454A-BE2B-7426DA6700B6}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU
-	EndGlobalSection
+		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.CEDMA Debug|Any CPU.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.CEDMA Debug|Any CPU.Build.0 = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.CEDMA Debug|x64.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.CEDMA Debug|x86.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Debug|Any CPU.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Debug|Any CPU.Build.0 = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Debug|x64.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Debug|x86.ActiveCfg = Debug|x86		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Modeling Debug|Any CPU.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Modeling Debug|Any CPU.Build.0 = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Modeling Debug|x64.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Modeling Debug|x86.ActiveCfg = Debug|x86		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Release|Any CPU.ActiveCfg = Release|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Release|Any CPU.Build.0 = Release|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Release|x64.ActiveCfg = Release|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Release|x86.ActiveCfg = Release|x86		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.v3.2 Debug|Any CPU.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.v3.2 Debug|Any CPU.Build.0 = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.v3.2 Debug|x64.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.v3.2 Debug|x86.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Visualization Debug|Any CPU.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Visualization Debug|Any CPU.Build.0 = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Visualization Debug|x64.ActiveCfg = Debug|Any CPU		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063}.Visualization Debug|x86.ActiveCfg = Debug|Any CPU	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -4122,5 +4122,5 @@
 		{589BECAE-69B0-4EB1-8C06-C073531762B7} = {410732DB-725A-4824-896B-C298978343C0}
 		{44456535-5DB5-454A-BE2B-7426DA6700B6} = {410732DB-725A-4824-896B-C298978343C0}
-		{A9E282EA-180F-4233-B809-AEDF0787545C} = {78982D7C-D63D-4A3D-AE1F-F58AC007603B}
+		{6EDEE199-61FC-48E1-AEDA-AF1C2E722063} = {410732DB-725A-4824-896B-C298978343C0}		{A9E282EA-180F-4233-B809-AEDF0787545C} = {78982D7C-D63D-4A3D-AE1F-F58AC007603B}
 		{BF7D9494-A586-457B-8DF9-ED599F9E6A71} = {78982D7C-D63D-4A3D-AE1F-F58AC007603B}
 		{C36BD924-A541-4A00-AFA8-41701378DDC5} = {78982D7C-D63D-4A3D-AE1F-F58AC007603B}
