Index: trunk/sources/HeuristicLab.CEDMA.Charting/HeuristicLab.CEDMA.Charting.csproj
===================================================================
--- trunk/sources/HeuristicLab.CEDMA.Charting/HeuristicLab.CEDMA.Charting.csproj	(revision 642)
+++ trunk/sources/HeuristicLab.CEDMA.Charting/HeuristicLab.CEDMA.Charting.csproj	(revision 656)
@@ -4,5 +4,5 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{1BF17271-5350-476A-8F6D-FC74FA3E82CA}</ProjectGuid>
@@ -122,7 +122,11 @@
       <Name>HeuristicLab.Data</Name>
     </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Functions\HeuristicLab.Functions.csproj">
-      <Project>{B95CA6E2-34BC-4430-994D-BD6E99375319}</Project>
-      <Name>HeuristicLab.Functions</Name>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
     </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Logging\HeuristicLab.Logging.csproj">
Index: trunk/sources/HeuristicLab.CEDMA.Charting/ModelView.cs
===================================================================
--- trunk/sources/HeuristicLab.CEDMA.Charting/ModelView.cs	(revision 642)
+++ trunk/sources/HeuristicLab.CEDMA.Charting/ModelView.cs	(revision 656)
@@ -9,8 +9,9 @@
 using HeuristicLab.Core;
 using HeuristicLab.Charting;
-using HeuristicLab.Functions;
 using HeuristicLab.Logging;
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Charting.Data;
+using HeuristicLab.GP;
+using HeuristicLab.GP.StructureIdentification;
 
 namespace HeuristicLab.CEDMA.Charting {
@@ -45,6 +46,6 @@
       Pen pen = new Pen(Color.FromArgb(80, Color.Blue));
       chart.AddDataRow(DataRowType.Points, pen, pen.Brush);
-      IEvaluator eval = model.CreateEvaluator();
-      eval.ResetEvaluator(model, dataset);
+      BakedTreeEvaluator eval = new BakedTreeEvaluator();
+      eval.ResetEvaluator((BakedFunctionTree)model, dataset);
       for(int i = 0; i < dataset.Rows; i += 10) {
         double predicted = eval.Evaluate(i);
@@ -83,6 +84,6 @@
       chart.AddDataRow(DataRowType.Lines, bluePen, bluePen.Brush);
       chart.AddDataRow(DataRowType.Lines, redPen, redPen.Brush);
-      IEvaluator eval = model.CreateEvaluator();
-      eval.ResetEvaluator(model, dataset);
+      BakedTreeEvaluator eval = new BakedTreeEvaluator();
+      eval.ResetEvaluator((BakedFunctionTree)model, dataset);
       int n = 0;
       for(int i = 0; i < dataset.Rows; i ++) {
Index: trunk/sources/HeuristicLab.CEDMA.Charting/ResultList.cs
===================================================================
--- trunk/sources/HeuristicLab.CEDMA.Charting/ResultList.cs	(revision 642)
+++ trunk/sources/HeuristicLab.CEDMA.Charting/ResultList.cs	(revision 656)
@@ -34,7 +34,7 @@
 using HeuristicLab.Data;
 using HeuristicLab.DataAnalysis;
-using HeuristicLab.Functions;
 using HeuristicLab.Charting.Data;
 using System.Drawing;
+using HeuristicLab.GP;
 
 namespace HeuristicLab.CEDMA.Charting {
Index: trunk/sources/HeuristicLab.GP.SantaFe/AntInterpreter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/AntInterpreter.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/AntInterpreter.cs	(revision 656)
@@ -28,5 +28,4 @@
 using System.Xml;
 using System.Diagnostics;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Evaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Evaluator.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Evaluator.cs	(revision 656)
@@ -26,5 +26,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
-using HeuristicLab.Functions;
 using HeuristicLab.DataAnalysis;
 
Index: trunk/sources/HeuristicLab.GP.SantaFe/FunctionLibraryInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/FunctionLibraryInjector.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/FunctionLibraryInjector.cs	(revision 656)
@@ -28,6 +28,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Constraints;
-using HeuristicLab.StructureIdentification;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
@@ -82,10 +80,10 @@
     }
 
-    private void SetAllowedSubOperators(HeuristicLab.Functions.IFunction f, HeuristicLab.Functions.IFunction[] gs) {
+    private void SetAllowedSubOperators(IFunction f, IFunction[] gs) {
       foreach(IConstraint c in f.Constraints) {
         if(c is SubOperatorTypeConstraint) {
           SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
           typeConstraint.Clear();
-          foreach(HeuristicLab.Functions.IFunction g in gs) {
+          foreach(IFunction g in gs) {
             typeConstraint.AddOperator(g);
           }
@@ -93,5 +91,5 @@
           AllSubOperatorsTypeConstraint typeConstraint = c as AllSubOperatorsTypeConstraint;
           typeConstraint.Clear();
-          foreach(HeuristicLab.Functions.IFunction g in gs) {
+          foreach(IFunction g in gs) {
             typeConstraint.AddOperator(g);
           }
Index: trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLab.GP.SantaFe.csproj
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLab.GP.SantaFe.csproj	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLab.GP.SantaFe.csproj	(revision 656)
@@ -95,7 +95,7 @@
       <Name>HeuristicLab.Data</Name>
     </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Functions\HeuristicLab.Functions.csproj">
-      <Project>{B95CA6E2-34BC-4430-994D-BD6E99375319}</Project>
-      <Name>HeuristicLab.Functions</Name>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
     </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
@@ -106,8 +106,4 @@
       <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
       <Name>HeuristicLab.Random</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.StructureIdentification\HeuristicLab.StructureIdentification.csproj">
-      <Project>{5948F299-0A5E-43B9-8F17-2D15298EEC34}</Project>
-      <Name>HeuristicLab.StructureIdentification</Name>
     </ProjectReference>
   </ItemGroup>
Index: trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLabGPSantaFePlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLabGPSantaFePlugin.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/HeuristicLabGPSantaFePlugin.cs	(revision 656)
@@ -28,4 +28,5 @@
   [ClassInfo(Name = "HeuristicLab.GP.SantaFe-3.2")]
   [PluginFile(Filename = "HeuristicLab.GP.SantaFe-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.GP-3.2")]
   [Dependency(Dependency = "HeuristicLab.Core-3.2")]
   [Dependency(Dependency = "HeuristicLab.Data-3.2")]
Index: trunk/sources/HeuristicLab.GP.SantaFe/IfFoodAhead.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/IfFoodAhead.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/IfFoodAhead.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Left.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Left.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Left.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Move.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Move.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Move.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Prog2.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Prog2.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Prog2.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Prog3.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Prog3.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Prog3.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/Right.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/Right.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/Right.cs	(revision 656)
@@ -29,5 +29,4 @@
 using HeuristicLab.DataAnalysis;
 using HeuristicLab.Random;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.SantaFe/SymbolTable.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.SantaFe/SymbolTable.cs	(revision 642)
+++ trunk/sources/HeuristicLab.GP.SantaFe/SymbolTable.cs	(revision 656)
@@ -26,5 +26,4 @@
 using HeuristicLab.Core;
 using System.Xml;
-using HeuristicLab.Functions;
 
 namespace HeuristicLab.GP.SantaFe {
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/AccuracyEvaluator.cs	(revision 656)
@@ -0,0 +1,93 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class AccuracyEvaluator : GPEvaluatorBase {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    private double[] thresholds;
+    private DoubleData accuracy;
+    public override string Description {
+      get {
+        return @"Calculates the total accuracy of the model (ratio of correctly classified instances to total number of instances) given a model and the list of possible target class values.";
+      }
+    }
+
+    public AccuracyEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Accuracy", "The total accuracy of the model (ratio of correctly classified instances to total number of instances)", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      accuracy = GetVariableValue<DoubleData>("Accuracy", scope, false, false);
+      if(accuracy == null) {
+        accuracy = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Accuracy"), accuracy));
+      }
+
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      thresholds = new double[classes.Count - 1];
+      for(int i = 0; i < classesArr.Length - 1; i++) {
+        thresholds[i] = (classesArr[i] + classesArr[i + 1]) / 2.0;
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      int nCorrect = 0;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double origClass = GetOriginalValue(sample);
+        double estClass = double.NaN;
+        // if estimation is lower than the smallest threshold value -> estimated class is the lower class
+        if(est < thresholds[0]) estClass = classesArr[0];
+        // if estimation is larger (or equal) than the largest threshold value -> estimated class is the upper class
+        else if(est >= thresholds[thresholds.Length - 1]) estClass = classesArr[classesArr.Length - 1];
+        else {
+          // otherwise the estimated class is the class which upper threshold is larger than the estimated value
+          for(int k = 0; k < thresholds.Length; k++) {
+            if(thresholds[k] > est) {
+              estClass = classesArr[k];
+              break;
+            }
+          }
+        }
+        SetOriginalValue(sample, estClass);
+        if(Math.Abs(estClass - origClass) < EPSILON) nCorrect++;
+      }
+      accuracy.Data = nCorrect / (double)nSamples;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMatrixEvaluator.cs	(revision 656)
@@ -0,0 +1,99 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class ClassificationMatrixEvaluator : GPEvaluatorBase {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    private double[] thresholds;
+    private IntMatrixData matrix;
+    public override string Description {
+      get {
+        return @"Calculates the classifcation matrix of the model.";
+      }
+    }
+
+    public ClassificationMatrixEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ClassificationMatrix", "The resulting classification matrix of the model", typeof(IntMatrixData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      thresholds = new double[classes.Count - 1];
+      for(int i = 0; i < classesArr.Length - 1; i++) {
+        thresholds[i] = (classesArr[i] + classesArr[i + 1]) / 2.0;
+      }
+
+      matrix = GetVariableValue<IntMatrixData>("ClassificationMatrix", scope, false, false);
+      if(matrix == null) {
+        matrix = new IntMatrixData(new int[classesArr.Length, classesArr.Length]);
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("ClassificationMatrix"), matrix));
+      }
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double origClass = GetOriginalValue(sample);
+        int estClassIndex = -1;
+        // if estimation is lower than the smallest threshold value -> estimated class is the lower class
+        if(est < thresholds[0]) estClassIndex = 0;
+        // if estimation is larger (or equal) than the largest threshold value -> estimated class is the upper class
+        else if(est >= thresholds[thresholds.Length - 1]) estClassIndex = classesArr.Length - 1;
+        else {
+          // otherwise the estimated class is the class which upper threshold is larger than the estimated value
+          for(int k = 0; k < thresholds.Length; k++) {
+            if(thresholds[k] > est) {
+              estClassIndex = k;
+              break;
+            }
+          }
+        }
+        SetOriginalValue(sample, classesArr[estClassIndex]);
+
+        int origClassIndex = -1;
+        for(int i = 0; i < classesArr.Length; i++) {
+          if(IsEqual(origClass, classesArr[i])) origClassIndex = i;
+        }
+        matrix.Data[origClassIndex, estClassIndex]++;
+      }
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/ClassificationMeanSquaredErrorEvaluator.cs	(revision 656)
@@ -0,0 +1,85 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class ClassificationMeanSquaredErrorEvaluator : MeanSquaredErrorEvaluator {
+    private const double EPSILON = 1.0E-6;
+    private double[] classesArr;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'DataSet' and calculates the mean-squared-error
+for the estimated values vs. the real values of 'TargetVariable'.";
+      }
+    }
+
+    public ClassificationMeanSquaredErrorEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("TargetClassValues", "The original class values of target variable (for instance negative=0 and positive=1).", typeof(ItemList<DoubleData>), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<DoubleData> classes = GetVariableValue<ItemList<DoubleData>>("TargetClassValues", scope, true);
+      classesArr = new double[classes.Count];
+      for(int i = 0; i < classesArr.Length; i++) classesArr[i] = classes[i].Data;
+      Array.Sort(classesArr);
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0;
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          double error = estimated - original;
+          // between classes use squared error
+          // on the lower end and upper end only add linear error if the absolute error is larger than 1
+          // the error>1.0 constraint is needed for balance because in the interval ]-1, 1[ the squared error is smaller than the absolute error
+          if((IsEqual(original, classesArr[0]) && error < -1.0) ||
+            (IsEqual(original, classesArr[classesArr.Length - 1]) && error > 1.0)) {
+            errorsSquaredSum += Math.Abs(error); // only add linear error below the smallest class or above the largest class
+          } else {
+            errorsSquaredSum += error * error;
+          }
+        }
+      }
+
+      errorsSquaredSum /= (end - start);
+      if(double.IsNaN(errorsSquaredSum) || double.IsInfinity(errorsSquaredSum)) {
+        errorsSquaredSum = double.MaxValue;
+      }
+      mse.Data = errorsSquaredSum;
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/CrossValidation.cs	(revision 656)
@@ -0,0 +1,109 @@
+#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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.Classification {
+  public class CrossValidation : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string NFOLD = "n-Fold";
+    private const string TRAININGSAMPLESSTART = "TrainingSamplesStart";
+    private const string TRAININGSAMPLESEND = "TrainingSamplesEnd";
+    private const string VALIDATIONSAMPLESSTART = "ValidationSamplesStart";
+    private const string VALIDATIONSAMPLESEND = "ValidationSamplesEnd";
+    private const string TESTSAMPLESSTART = "TestSamplesStart";
+    private const string TESTSAMPLESEND = "TestSamplesEnd";
+
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public CrossValidation()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The original dataset and the new datasets in the newly created subscopes", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(NFOLD, "Number of folds for the cross-validation", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESSTART, "The start of training samples in the original dataset and starts of training samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESEND, "The end of training samples in the original dataset and ends of training samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESSTART, "The start of validation samples in the original dataset and starts of validation samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESEND, "The end of validation samples in the original dataset and ends of validation samples in the new datasets", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TESTSAMPLESSTART, "The start of the test samples in the new datasets", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(TESTSAMPLESEND, "The end of the test samples in the new datasets", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset origDataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int nFolds = GetVariableValue<IntData>(NFOLD, scope, true).Data;
+      int origTrainingSamplesStart = GetVariableValue<IntData>(TRAININGSAMPLESSTART, scope, true).Data;
+      int origTrainingSamplesEnd = GetVariableValue<IntData>(TRAININGSAMPLESEND, scope, true).Data;
+      int origValidationSamplesStart = GetVariableValue<IntData>(VALIDATIONSAMPLESSTART, scope, true).Data;
+      int origValidationSamplesEnd = GetVariableValue<IntData>(VALIDATIONSAMPLESEND, scope, true).Data;
+      int n=origDataset.Rows;
+      int origTrainingSamples = (origTrainingSamplesEnd-origTrainingSamplesStart);
+      int origValidationSamples = (origValidationSamplesEnd-origValidationSamplesStart);
+
+      double percentTrainingSamples = origTrainingSamples / (double)(origValidationSamples + origTrainingSamples);
+      int nTestSamples = n / nFolds;
+
+      int newTrainingSamplesStart = 0;
+      int newTrainingSamplesEnd = (int)((n - nTestSamples) * percentTrainingSamples);
+      int newValidationSamplesStart = newTrainingSamplesEnd;
+      int newValidationSamplesEnd = n - nTestSamples;
+      int newTestSamplesStart = n - nTestSamples;
+      int newTestSamplesEnd = n;
+
+      for(int i = 0; i < nFolds; i++) {
+        Scope childScope = new Scope(i.ToString());
+        Dataset rotatedSet = new Dataset();
+
+        double[] samples = new double[origDataset.Samples.Length];
+        Array.Copy(origDataset.Samples, samples, samples.Length);
+        RotateArray(samples, i * nTestSamples * origDataset.Columns);
+
+        rotatedSet.Rows = origDataset.Rows;
+        rotatedSet.Columns = origDataset.Columns;
+        rotatedSet.Samples = samples;
+        childScope.AddVariable(new Variable(scope.TranslateName(DATASET), rotatedSet));
+        childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESSTART), new IntData(newTrainingSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESEND), new IntData(newTrainingSamplesEnd)));
+        childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESSTART), new IntData(newValidationSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESEND), new IntData(newValidationSamplesEnd)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TESTSAMPLESSTART), new IntData(newTestSamplesStart)));
+        childScope.AddVariable(new Variable(scope.TranslateName(TESTSAMPLESEND), new IntData(newTestSamplesEnd)));
+
+        scope.AddSubScope(childScope);
+      }
+      return null;
+    }
+
+    private void RotateArray(double[] samples, int p) {
+      Array.Reverse(samples, 0, p);
+      Array.Reverse(samples, p, samples.Length - p);
+      Array.Reverse(samples);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/FunctionLibraryInjector.cs	(revision 656)
@@ -0,0 +1,207 @@
+#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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Constraints;
+using StructId = HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class FunctionLibraryInjector : OperatorBase {
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string ALLOWEDFEATURES = "AllowedFeatures";
+    private const string FUNCTIONLIBRARY = "FunctionLibrary";
+
+    private StructId.Variable variable;
+    private GPOperatorLibrary operatorLibrary;
+
+    public override string Description {
+      get { return @"Injects a default function library for classification problems."; }
+    }
+
+    public FunctionLibraryInjector()
+      : base() {
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(ALLOWEDFEATURES, "List of indexes of allowed features", typeof(ItemList<IntData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(FUNCTIONLIBRARY, "Preconfigured default operator library", typeof(GPOperatorLibrary), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      ItemList<IntData> allowedFeatures = GetVariableValue<ItemList<IntData>>(ALLOWEDFEATURES, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+
+      // remove the target-variable in case it occures in allowed features
+      List<IntData> ts = allowedFeatures.FindAll(d => d.Data == targetVariable);
+      foreach(IntData t in ts) allowedFeatures.Remove(t);
+
+      InitDefaultOperatorLibrary();
+
+      int[] allowedIndexes = new int[allowedFeatures.Count];
+      for(int i = 0; i < allowedIndexes.Length; i++) {
+        allowedIndexes[i] = allowedFeatures[i].Data;
+      }
+
+      scope.AddVariable(new Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
+      return null;
+    }
+
+    private void InitDefaultOperatorLibrary() {
+      variable = new StructId.Variable();
+      StructId.Constant constant = new StructId.Constant();
+
+      StructId.Addition addition = new StructId.Addition();
+      StructId.And and = new StructId.And();
+      StructId.Average average = new StructId.Average();
+      StructId.Cosinus cosinus = new StructId.Cosinus();
+      StructId.Division division = new StructId.Division();
+      StructId.Equal equal = new StructId.Equal();
+      StructId.Exponential exponential = new StructId.Exponential();
+      StructId.GreaterThan greaterThan = new StructId.GreaterThan();
+      StructId.IfThenElse ifThenElse = new StructId.IfThenElse();
+      StructId.LessThan lessThan = new StructId.LessThan();
+      StructId.Logarithm logarithm = new StructId.Logarithm();
+      StructId.Multiplication multiplication = new StructId.Multiplication();
+      StructId.Not not = new StructId.Not();
+      StructId.Or or = new StructId.Or();
+      StructId.Power power = new StructId.Power();
+      StructId.Signum signum = new StructId.Signum();
+      StructId.Sinus sinus = new StructId.Sinus();
+      StructId.Sqrt sqrt = new StructId.Sqrt();
+      StructId.Subtraction subtraction = new StructId.Subtraction();
+      StructId.Tangens tangens = new StructId.Tangens();
+      StructId.Xor xor = new StructId.Xor();
+
+      IFunction[] booleanFunctions = new IFunction[] {
+        and,
+        equal,
+        greaterThan,
+        lessThan,
+        not,
+        or,
+        xor 
+      };
+      IFunction[] doubleFunctions = new IFunction[] {
+        variable,
+        constant,
+        addition,
+        average,
+        cosinus,
+        division,
+        exponential,
+        ifThenElse,
+        logarithm,
+        multiplication,
+        power,
+        signum,
+        sinus,
+        sqrt,
+        subtraction,
+        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);
+
+      operatorLibrary = new GPOperatorLibrary();
+      operatorLibrary.GPOperatorGroup.AddOperator(variable);
+      operatorLibrary.GPOperatorGroup.AddOperator(constant);
+      operatorLibrary.GPOperatorGroup.AddOperator(addition);
+      operatorLibrary.GPOperatorGroup.AddOperator(average);
+      operatorLibrary.GPOperatorGroup.AddOperator(and);
+      operatorLibrary.GPOperatorGroup.AddOperator(cosinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(division);
+      operatorLibrary.GPOperatorGroup.AddOperator(equal);
+      operatorLibrary.GPOperatorGroup.AddOperator(exponential);
+      operatorLibrary.GPOperatorGroup.AddOperator(greaterThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(ifThenElse);
+      operatorLibrary.GPOperatorGroup.AddOperator(lessThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(logarithm);
+      operatorLibrary.GPOperatorGroup.AddOperator(multiplication);
+      operatorLibrary.GPOperatorGroup.AddOperator(not);
+      operatorLibrary.GPOperatorGroup.AddOperator(power);
+      operatorLibrary.GPOperatorGroup.AddOperator(or);
+      operatorLibrary.GPOperatorGroup.AddOperator(signum);
+      operatorLibrary.GPOperatorGroup.AddOperator(sinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(sqrt);
+      operatorLibrary.GPOperatorGroup.AddOperator(subtraction);
+      operatorLibrary.GPOperatorGroup.AddOperator(tangens);
+      operatorLibrary.GPOperatorGroup.AddOperator(xor);
+    }
+
+    private void SetAllowedSubOperators(IFunction f, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        } else if(c is AllSubOperatorsTypeConstraint) {
+          AllSubOperatorsTypeConstraint typeConstraint = c as AllSubOperatorsTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        }
+      }
+    }
+
+    private void SetAllowedSubOperators(IFunction f, int p, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          if(typeConstraint.SubOperatorIndex.Data == p) {
+            typeConstraint.Clear();
+            foreach(IFunction g in gs) {
+              typeConstraint.AddOperator(g);
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLab.GP.StructureIdentification.Classification.csproj	(revision 656)
@@ -0,0 +1,124 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<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.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7C20D100-8BEB-433A-9499-F075E2CB9297}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.Classification</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.StructureIdentification.Classification-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </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="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AccuracyEvaluator.cs" />
+    <Compile Include="ClassificationMatrixEvaluator.cs" />
+    <Compile Include="ClassificationMeanSquaredErrorEvaluator.cs" />
+    <Compile Include="CrossValidation.cs" />
+    <Compile Include="FunctionLibraryInjector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="HeuristicLabGPClassificationPlugin.cs" />
+    <Compile Include="MCCEvaluator.cs" />
+    <Compile Include="MulticlassModeller.cs" />
+    <Compile Include="MulticlassOneVsOneAnalyzer.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\HeuristicLab.DataAnalysis.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </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>cmd /c ""$(SolutionDir)PreBuildEvent.cmd" "$(ProjectDir).""</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/HeuristicLabGPClassificationPlugin.cs	(revision 656)
@@ -0,0 +1,40 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP.Classification {
+  [ClassInfo(Name = "HeuristicLab.GP.StructureIdentification.Classification-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP.StructureIdentification.Classification-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP.StructureIdentification-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  public class HeuristicLabGPClassificationPlugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MCCEvaluator.cs	(revision 656)
@@ -0,0 +1,95 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class MCCEvaluator : GPEvaluatorBase {
+    private double limit;
+    private double[] original = new double[1];
+    private double[] estimated = new double[1];
+    private DoubleData mcc;
+    public override string Description {
+      get {
+        return @"Calculates the matthews correlation coefficient for a given model and class separation threshold";
+      }
+    }
+    public MCCEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ClassSeparation", "The value of separation between negative and positive target classification values (for instance 0.5 if negative=0 and positive=1).", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MCC", "The matthews correlation coefficient of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      mcc = GetVariableValue<DoubleData>("MCC", scope, false, false);
+      if(mcc == null) {
+        mcc = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("MCC"), mcc));
+      }
+      limit = GetVariableValue<DoubleData>("ClassSeparation", scope, true).Data;
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      if(estimated.Length != nSamples) {
+        estimated = new double[nSamples];
+        original = new double[nSamples];
+      }
+
+      double positive = 0;
+      double negative = 0;
+      for(int sample = start; sample < end; sample++) {
+        double est = GetEstimatedValue(sample);
+        double orig = GetOriginalValue(sample);
+        SetOriginalValue(sample, est);
+        estimated[sample - start] = est;
+        original[sample - start] = orig;
+        if(orig >= limit) positive++;
+        else negative++;
+      }
+      Array.Sort(estimated, original);
+      double best_mcc = -1.0;
+      double tp = 0;
+      double fn = positive;
+      double tn = negative;
+      double fp = 0;
+      for(int i = original.Length - 1; i >= 0; i--) {
+        if(original[i] >= limit) {
+          tp++; fn--;
+        } else {
+          tn--; fp++;
+        }
+        double mcc = (tp * tn - fp * fn) / Math.Sqrt(positive * (tp + fn) * (tn + fp) * negative);
+        if(best_mcc < mcc) {
+          best_mcc = mcc;
+        }
+      }
+      this.mcc.Data = best_mcc;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassModeller.cs	(revision 656)
@@ -0,0 +1,150 @@
+#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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.Classification {
+  public class MulticlassModeller : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string TARGETCLASSVALUES = "TargetClassValues";
+    private const string TRAININGSAMPLESSTART = "TrainingSamplesStart";
+    private const string TRAININGSAMPLESEND = "TrainingSamplesEnd";
+    private const string VALIDATIONSAMPLESSTART = "ValidationSamplesStart";
+    private const string VALIDATIONSAMPLESEND = "ValidationSamplesEnd";
+    private const string CLASSAVALUE = "ClassAValue";
+    private const string CLASSBVALUE = "ClassBValue";
+    private const double EPSILON = 1E-6;
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public MulticlassModeller()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The original dataset and the new dataset parts in the newly created subscopes", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "TargetVariable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETCLASSVALUES, "Class values of the target variable in the original dataset and in the new dataset parts", typeof(ItemList<DoubleData>), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(CLASSAVALUE, "The original class value of the new class A", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(CLASSBVALUE, "The original class value of the new class B", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESSTART, "The start of training samples in the original dataset and starts of training samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(TRAININGSAMPLESEND, "The end of training samples in the original dataset and ends of training samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESSTART, "The start of validation samples in the original dataset and starts of validation samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo(VALIDATIONSAMPLESEND, "The end of validation samples in the original dataset and ends of validation samples in the new dataset parts", typeof(IntData), VariableKind.In | VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset origDataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      ItemList<DoubleData> classValues = GetVariableValue<ItemList<DoubleData>>(TARGETCLASSVALUES, scope, true);
+      int origTrainingSamplesStart = GetVariableValue<IntData>(TRAININGSAMPLESSTART, scope, true).Data;
+      int origTrainingSamplesEnd = GetVariableValue<IntData>(TRAININGSAMPLESEND, scope, true).Data;
+      int origValidationSamplesStart = GetVariableValue<IntData>(VALIDATIONSAMPLESSTART, scope, true).Data;
+      int origValidationSamplesEnd = GetVariableValue<IntData>(VALIDATIONSAMPLESEND, scope, true).Data;
+      ItemList<DoubleData> binaryClassValues = new ItemList<DoubleData>();
+      binaryClassValues.Add(new DoubleData(0.0));
+      binaryClassValues.Add(new DoubleData(1.0));
+      for(int i = 0; i < classValues.Count-1; i++) {
+        for(int j = i+1; j < classValues.Count; j++) {
+          Dataset dataset = new Dataset();
+          dataset.Columns = origDataset.Columns;
+          double classAValue = classValues[i].Data;
+          double classBValue = classValues[j].Data;
+          int trainingSamplesStart;
+          int trainingSamplesEnd;
+          int validationSamplesStart;
+          int validationSamplesEnd;
+
+          trainingSamplesStart = 0;
+          List<double[]> rows = new List<double[]>();
+          for(int k = origTrainingSamplesStart; k < origTrainingSamplesEnd; k++) {
+            double[] row = new double[dataset.Columns];
+            double targetValue = origDataset.GetValue(k, targetVariable);
+            if(IsEqual(targetValue, classAValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 0;
+              rows.Add(row);
+            } else if(IsEqual(targetValue, classBValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 1.0;
+              rows.Add(row);
+            }
+          }
+          trainingSamplesEnd = rows.Count;
+          validationSamplesStart = rows.Count;
+          for(int k = origValidationSamplesStart; k < origValidationSamplesEnd; k++) {
+            double[] row = new double[dataset.Columns];
+            double targetValue = origDataset.GetValue(k, targetVariable);
+            if(IsEqual(targetValue, classAValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 0;
+              rows.Add(row);
+            } else if(IsEqual(targetValue, classBValue)) {
+              for(int l = 0; l < row.Length; l++) {
+                row[l] = origDataset.GetValue(k, l);
+              }
+              row[targetVariable] = 1.0;
+              rows.Add(row);
+            }
+          }
+          validationSamplesEnd = rows.Count;
+
+          dataset.Rows = rows.Count;
+          dataset.Samples = new double[dataset.Rows * dataset.Columns];
+          for(int k = 0; k < dataset.Rows; k++) {
+            for(int l = 0; l < dataset.Columns; l++) {
+              dataset.SetValue(k, l, rows[k][l]);
+            }
+          }
+
+          Scope childScope = new Scope(classAValue+" vs. "+classBValue);
+
+          childScope.AddVariable(new Variable(scope.TranslateName(TARGETCLASSVALUES), binaryClassValues));
+          childScope.AddVariable(new Variable(scope.TranslateName(CLASSAVALUE), new DoubleData(classAValue)));
+          childScope.AddVariable(new Variable(scope.TranslateName(CLASSBVALUE), new DoubleData(classBValue)));
+          childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESSTART), new IntData(trainingSamplesStart)));
+          childScope.AddVariable(new Variable(scope.TranslateName(TRAININGSAMPLESEND), new IntData(trainingSamplesEnd)));
+          childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESSTART), new IntData(validationSamplesStart)));
+          childScope.AddVariable(new Variable(scope.TranslateName(VALIDATIONSAMPLESEND), new IntData(validationSamplesEnd)));
+          childScope.AddVariable(new Variable(scope.TranslateName(DATASET), dataset));
+          scope.AddSubScope(childScope);
+        }
+      }
+      return null;
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/MulticlassOneVsOneAnalyzer.cs	(revision 656)
@@ -0,0 +1,128 @@
+#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.Text;
+using System.Xml;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.Classification {
+  public class MulticlassOneVsOneAnalyzer : OperatorBase {
+
+    private const string DATASET = "Dataset";
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string TARGETCLASSVALUES = "TargetClassValues";
+    private const string SAMPLESSTART = "SamplesStart";
+    private const string SAMPLESEND = "SamplesEnd";
+    private const string CLASSAVALUE = "ClassAValue";
+    private const string CLASSBVALUE = "ClassBValue";
+    private const string BESTMODELLSCOPE = "BestValidationSolution";
+    private const string BESTMODELL = "FunctionTree";
+    private const string VOTES = "Votes";
+    private const string ACCURACY = "Accuracy";
+
+    private const double EPSILON = 1E-6;
+    public override string Description {
+      get { return @"TASK"; }
+    }
+
+    public MulticlassOneVsOneAnalyzer()
+      : base() {
+      AddVariableInfo(new VariableInfo(DATASET, "The dataset to use", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "Target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(TARGETCLASSVALUES, "Class values of the target variable in the original dataset", typeof(ItemList<DoubleData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(CLASSAVALUE, "The original class value of the class A in the subscope", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(CLASSBVALUE, "The original class value of the class B in the subscope", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(SAMPLESSTART, "The start of samples in the original dataset", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(SAMPLESEND, "The end of samples in the original dataset", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(BESTMODELLSCOPE, "The variable containing the scope of the model (incl. meta data)", typeof(IScope), VariableKind.In));
+      AddVariableInfo(new VariableInfo(BESTMODELL, "The variable in the scope of the model that contains the actual model", typeof(BakedFunctionTree), VariableKind.In));
+      AddVariableInfo(new VariableInfo(VOTES, "Array with the votes for each instance", typeof(IntMatrixData), VariableKind.New));
+      AddVariableInfo(new VariableInfo(ACCURACY, "Accuracy of the one-vs-one multi-cass classifier", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      Dataset dataset = GetVariableValue<Dataset>(DATASET, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      int samplesStart = GetVariableValue<IntData>(SAMPLESSTART, scope, true).Data;
+      int samplesEnd = GetVariableValue<IntData>(SAMPLESEND, scope, true).Data;
+      ItemList<DoubleData> classValues = GetVariableValue<ItemList<DoubleData>>(TARGETCLASSVALUES, scope, true);
+      int[,] votes = new int[samplesEnd - samplesStart, classValues.Count];
+
+      foreach(IScope childScope in scope.SubScopes) {
+        double classAValue = GetVariableValue<DoubleData>(CLASSAVALUE, childScope, true).Data;
+        double classBValue = GetVariableValue<DoubleData>(CLASSBVALUE, childScope, true).Data;
+        IScope bestScope = GetVariableValue<IScope>(BESTMODELLSCOPE, childScope, true);
+        BakedFunctionTree functionTree = GetVariableValue<BakedFunctionTree>(BESTMODELL, bestScope, true);
+
+        BakedTreeEvaluator evaluator = new BakedTreeEvaluator();
+        evaluator.ResetEvaluator(functionTree, dataset);
+
+        for(int i = 0; i < (samplesEnd - samplesStart); i++) {
+          double est = evaluator.Evaluate(i + samplesStart);
+          if(est < 0.5) {
+            CastVote(votes, i, classAValue, classValues);
+          } else {
+            CastVote(votes, i, classBValue, classValues);
+          }
+        }
+      }
+
+      int correctlyClassified = 0;
+      for(int i = 0; i < (samplesEnd - samplesStart); i++) {
+        double originalClassValue = dataset.GetValue(i + samplesStart, targetVariable);
+        double estimatedClassValue = classValues[0].Data;
+        int maxVotes = votes[i, 0];
+        int sameVotes = 0;
+        for(int j = 1; j < classValues[j].Data; j++) {
+          if(votes[i, j] > maxVotes) {
+            maxVotes = votes[i, j];
+            estimatedClassValue = classValues[j].Data;
+            sameVotes = 0;
+          } else if(votes[i, j] == maxVotes) {
+            sameVotes++;
+          }
+        }
+        if(IsEqual(originalClassValue, estimatedClassValue) && sameVotes == 0) correctlyClassified++;
+      }
+
+      double accuracy = correctlyClassified / (double)(samplesEnd - samplesStart);
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(VOTES), new IntMatrixData(votes)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(ACCURACY), new DoubleData(accuracy)));
+      return null;
+    }
+
+    private void CastVote(int[,] votes, int sample, double votedClass, ItemList<DoubleData> classValues) {
+      for(int i = 0; i < classValues.Count; i++) {
+        if(IsEqual(classValues[i].Data, votedClass)) votes[sample, i]++;
+      }
+    }
+
+    private bool IsEqual(double x, double y) {
+      return Math.Abs(x - y) < EPSILON;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.frame	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.Classification/Properties/AssemblyInfo.frame	(revision 656)
@@ -0,0 +1,58 @@
+#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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.StructureIdentification.Classification")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2008 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("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// 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.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/AveragePercentageChangeEvaluator.cs	(revision 656)
@@ -0,0 +1,91 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class AvergePercentageChangeEvaluator : GPEvaluatorBase {
+    protected DoubleData apc;
+    private bool differential;
+    public override string Description {
+      get {
+        return @"TASK";
+      }
+    }
+
+    public AvergePercentageChangeEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Differential", "Wether to transform the target variable to percentage change first or not.", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("APC", "The average percentage change of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      differential = GetVariableValue<BoolData>("Differential", scope, true).Data;
+      apc = GetVariableValue<DoubleData>("APC", scope, false, false);
+      if(apc == null) {
+        apc = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("APC"), apc));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double percentageSum = 0;
+      for(int sample = start; sample < end; sample++) {
+        double prevOriginal;
+        double originalPercentageChange;
+        double estimatedPercentageChange;
+        if(differential) {
+          prevOriginal = GetOriginalValue(sample - 1);
+          originalPercentageChange = (GetOriginalValue(sample) - prevOriginal) / prevOriginal;
+          estimatedPercentageChange = (GetEstimatedValue(sample) - prevOriginal) / prevOriginal;
+          SetOriginalValue(sample, estimatedPercentageChange*prevOriginal + prevOriginal);
+        } else {
+          originalPercentageChange = GetOriginalValue(sample);
+          estimatedPercentageChange = GetEstimatedValue(sample);
+          SetOriginalValue(sample, estimatedPercentageChange);
+        }
+        if(!double.IsNaN(originalPercentageChange) && !double.IsInfinity(originalPercentageChange)) {
+          if((estimatedPercentageChange > 0 && originalPercentageChange > 0) ||
+            (estimatedPercentageChange < 0 && originalPercentageChange < 0)) {
+            percentageSum += Math.Abs(originalPercentageChange);
+          } else if((estimatedPercentageChange > 0 && originalPercentageChange < 0) ||
+            (estimatedPercentageChange < 0 && originalPercentageChange > 0)) {
+            percentageSum -= Math.Abs(originalPercentageChange);
+          }
+        }
+      }
+
+      percentageSum /= (end - start);
+      if(double.IsNaN(percentageSum) || double.IsInfinity(percentageSum)) {
+        percentageSum = double.MinValue;
+      }
+      apc.Data = percentageSum;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/FunctionLibraryInjector.cs	(revision 656)
@@ -0,0 +1,222 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using StructId = HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class FunctionLibraryInjector : OperatorBase {
+    private const string TARGETVARIABLE = "TargetVariable";
+    private const string AUTOREGRESSIVE = "Autoregressive";
+    private const string ALLOWEDFEATURES = "AllowedFeatures";
+    private const string MINTIMEOFFSET = "MinTimeOffset";
+    private const string MAXTIMEOFFSET = "MaxTimeOffset";
+    private const string FUNCTIONLIBRARY = "FunctionLibrary";
+
+    private StructId.Variable variable;
+    private StructId.Differential differential;
+    private GPOperatorLibrary operatorLibrary;
+
+    public override string Description {
+      get { return @"Injects a default function library for time series modeling."; }
+    }
+
+    public FunctionLibraryInjector()
+      : base() {
+      AddVariableInfo(new VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(AUTOREGRESSIVE, "Switch to turn on/off autoregressive modeling (wether to allow the target variable as input)", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(ALLOWEDFEATURES, "List of indexes of allowed features", typeof(ItemList<IntData>), VariableKind.In));
+      AddVariableInfo(new VariableInfo(MINTIMEOFFSET, "Minimal time offset for all features", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(MAXTIMEOFFSET, "Maximal time offset for all feature", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo(FUNCTIONLIBRARY, "Preconfigured default operator library", typeof(GPOperatorLibrary), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IntData minTimeOffset = GetVariableValue<IntData>(MINTIMEOFFSET, scope, true);
+      IntData maxTimeOffset = GetVariableValue<IntData>(MAXTIMEOFFSET, scope, true);
+      ItemList<IntData> allowedFeatures = GetVariableValue<ItemList<IntData>>(ALLOWEDFEATURES, scope, true);
+      int targetVariable = GetVariableValue<IntData>(TARGETVARIABLE, scope, true).Data;
+      bool autoregressive = GetVariableValue<BoolData>(AUTOREGRESSIVE, scope, true).Data;
+
+      if(autoregressive) {
+        // make sure the target-variable occures in list of allowed features
+        if(!allowedFeatures.Exists(d => d.Data == targetVariable)) allowedFeatures.Add(new IntData(targetVariable));
+      } else {
+        // remove the target-variable in case it occures in allowed features
+        List<IntData> ts = allowedFeatures.FindAll(d => d.Data == targetVariable);
+        foreach(IntData t in ts) allowedFeatures.Remove(t);
+      }
+
+      InitDefaultOperatorLibrary();
+
+      int[] allowedIndexes = new int[allowedFeatures.Count];
+      for(int i = 0; i < allowedIndexes.Length; i++) {
+        allowedIndexes[i] = allowedFeatures[i].Data;
+      }
+
+      variable.SetConstraints(allowedIndexes, minTimeOffset.Data, maxTimeOffset.Data);
+      differential.SetConstraints(allowedIndexes, minTimeOffset.Data, maxTimeOffset.Data);
+
+      scope.AddVariable(new Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
+      return null;
+    }
+
+    private void InitDefaultOperatorLibrary() {
+      variable = new StructId.Variable();
+      differential = new StructId.Differential();
+      StructId.Constant constant = new StructId.Constant();
+
+      StructId.Addition addition = new StructId.Addition();
+      StructId.And and = new StructId.And();
+      StructId.Average average = new StructId.Average();
+      StructId.Cosinus cosinus = new StructId.Cosinus();
+      StructId.Division division = new StructId.Division();
+      StructId.Equal equal = new StructId.Equal();
+      StructId.Exponential exponential = new StructId.Exponential();
+      StructId.GreaterThan greaterThan = new StructId.GreaterThan();
+      StructId.IfThenElse ifThenElse = new StructId.IfThenElse();
+      StructId.LessThan lessThan = new StructId.LessThan();
+      StructId.Logarithm logarithm = new StructId.Logarithm();
+      StructId.Multiplication multiplication = new StructId.Multiplication();
+      StructId.Not not = new StructId.Not();
+      StructId.Or or = new StructId.Or();
+      StructId.Power power = new StructId.Power();
+      StructId.Signum signum = new StructId.Signum();
+      StructId.Sinus sinus = new StructId.Sinus();
+      StructId.Sqrt sqrt = new StructId.Sqrt();
+      StructId.Subtraction subtraction = new StructId.Subtraction();
+      StructId.Tangens tangens = new StructId.Tangens();
+      StructId.Xor xor = new StructId.Xor();
+
+      IFunction[] booleanFunctions = new IFunction[] {
+        and,
+        equal,
+        greaterThan,
+        lessThan,
+        not,
+        or,
+        xor };
+      IFunction[] doubleFunctions = new IFunction[] {
+        variable,
+        differential,
+        constant,
+        addition,
+        average,
+        cosinus,
+        division,
+        exponential,
+        ifThenElse,
+        logarithm,
+        multiplication,
+        power,
+        signum,
+        sinus,
+        sqrt,
+        subtraction,
+        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);
+
+      operatorLibrary = new GPOperatorLibrary();
+      operatorLibrary.GPOperatorGroup.AddOperator(variable);
+      operatorLibrary.GPOperatorGroup.AddOperator(differential);
+      operatorLibrary.GPOperatorGroup.AddOperator(constant);
+      operatorLibrary.GPOperatorGroup.AddOperator(addition);
+      operatorLibrary.GPOperatorGroup.AddOperator(average);
+      operatorLibrary.GPOperatorGroup.AddOperator(and);
+      operatorLibrary.GPOperatorGroup.AddOperator(cosinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(division);
+      operatorLibrary.GPOperatorGroup.AddOperator(equal);
+      operatorLibrary.GPOperatorGroup.AddOperator(exponential);
+      operatorLibrary.GPOperatorGroup.AddOperator(greaterThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(ifThenElse);
+      operatorLibrary.GPOperatorGroup.AddOperator(lessThan);
+      operatorLibrary.GPOperatorGroup.AddOperator(logarithm);
+      operatorLibrary.GPOperatorGroup.AddOperator(multiplication);
+      operatorLibrary.GPOperatorGroup.AddOperator(not);
+      operatorLibrary.GPOperatorGroup.AddOperator(power);
+      operatorLibrary.GPOperatorGroup.AddOperator(or);
+      operatorLibrary.GPOperatorGroup.AddOperator(signum);
+      operatorLibrary.GPOperatorGroup.AddOperator(sinus);
+      operatorLibrary.GPOperatorGroup.AddOperator(sqrt);
+      operatorLibrary.GPOperatorGroup.AddOperator(subtraction);
+      operatorLibrary.GPOperatorGroup.AddOperator(tangens);
+      operatorLibrary.GPOperatorGroup.AddOperator(xor);
+    }
+
+    private void SetAllowedSubOperators(IFunction f, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        } else if(c is AllSubOperatorsTypeConstraint) {
+          AllSubOperatorsTypeConstraint typeConstraint = c as AllSubOperatorsTypeConstraint;
+          typeConstraint.Clear();
+          foreach(IFunction g in gs) {
+            typeConstraint.AddOperator(g);
+          }
+        }
+      }
+    }
+
+    private void SetAllowedSubOperators(IFunction f, int p, IFunction[] gs) {
+      foreach(IConstraint c in f.Constraints) {
+        if(c is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint typeConstraint = c as SubOperatorTypeConstraint;
+          if(typeConstraint.SubOperatorIndex.Data == p) {
+            typeConstraint.Clear();
+            foreach(IFunction g in gs) {
+              typeConstraint.AddOperator(g);
+            }
+          }
+        }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 656)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<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.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6084CFB5-733F-449D-9F92-2E40D13F0514}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.TimeSeries</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.StructureIdentification.TimeSeries-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </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="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AveragePercentageChangeEvaluator.cs" />
+    <Compile Include="FunctionLibraryInjector.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="HeuristicLabGPTimeSeriesPlugin.cs" />
+    <Compile Include="ProfitEvaluator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TheilInequalityCoefficientEvaluator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\HeuristicLab.DataAnalysis.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj">
+      <Project>{74223A32-C726-4978-BE78-37113A18373C}</Project>
+      <Name>HeuristicLab.GP.StructureIdentification</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </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>cmd /c ""$(SolutionDir)PreBuildEvent.cmd" "$(ProjectDir).""</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/HeuristicLabGPTimeSeriesPlugin.cs	(revision 656)
@@ -0,0 +1,38 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP.TimeSeries {
+  [ClassInfo(Name = "HeuristicLab.GP.StructureIdentification.TimeSeries-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP.StructureIdentification.TimeSeries-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP.StructureIdentification-3.2")]
+  public class HeuristicLabGPTimeSeriesPlugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/ProfitEvaluator.cs	(revision 656)
@@ -0,0 +1,92 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class ProfitEvaluator : GPEvaluatorBase {
+    protected DoubleData profit;
+    private int exchangeRateVarIndex;
+    private double transactionCost;
+    public override string Description {
+      get {
+        return @"TASK";
+      }
+    }
+
+    public ProfitEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("ExchangeRate", "The index of the variable in the dataset for the exchange rate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Profit", "The estimated profit of the model", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TransactionCost", "Cost of a trade in percent of the transaction volume (0..1)", typeof(DoubleData), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      exchangeRateVarIndex = GetVariableValue<IntData>("ExchangeRate", scope, true).Data;
+      transactionCost = GetVariableValue<DoubleData>("TransactionCost", scope, true).Data;
+      profit = GetVariableValue<DoubleData>("Profit", scope, false, false);
+      if(profit == null) {
+        profit = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Profit"), profit));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double cA = 1.0; // start with a capital of one entity of A
+      double cB = 0;
+      double exchangeRate = double.MaxValue;
+      for(int sample = start; sample < end; sample++) {
+        exchangeRate = dataset.GetValue(sample, exchangeRateVarIndex);
+        double originalPercentageChange = GetOriginalValue(sample);
+        double estimatedPercentageChange = GetEstimatedValue(sample);
+        SetOriginalValue(sample, estimatedPercentageChange);
+        if(!double.IsNaN(originalPercentageChange) && !double.IsInfinity(originalPercentageChange)) {
+          if(estimatedPercentageChange > 0) {
+            // prediction is the rate of B/A will increase (= get more B for one A) => exchange all B to A
+            cA += (cB / exchangeRate) * (1-transactionCost);
+            cB = 0;
+          } else if(estimatedPercentageChange < 0) {
+            // prediction is the rate of B/A will drop (= get more A for one B) => exchange all A to B
+            cB += (cA * exchangeRate) * (1-transactionCost);
+            cA = 0;
+          }
+        }
+      }
+
+      if(double.IsNaN(cA) || double.IsInfinity(cA) || double.IsInfinity(cB) || double.IsNaN(cB)) {
+        cA = 0;
+        cB = 0;
+      }
+      // at the end we must exchange all B back to A 
+      // (because we want to buy the local beer not import one from B-country)
+      profit.Data = cA + ((cB / exchangeRate) * (1-transactionCost));
+      profit.Data -= 1.0; // substract the start capital to determine actual profit
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.frame	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/Properties/AssemblyInfo.frame	(revision 656)
@@ -0,0 +1,58 @@
+#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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.StructureIdentification.TimeSeries")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2008 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("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// 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.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification.TimeSeries/TheilInequalityCoefficientEvaluator.cs	(revision 656)
@@ -0,0 +1,83 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.TimeSeries {
+  public class TheilInequalityCoefficientEvaluator : GPEvaluatorBase {
+    private bool differential;
+    private DoubleData theilInequaliy;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'Dataset' and calculates
+the 'Theil inequality coefficient (scale invariant)' of estimated values vs. real values of 'TargetVariable'.";
+      }
+    }
+
+    public TheilInequalityCoefficientEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Differential", "Wether to calculate the coefficient for the predicted change vs. original change or for the absolute prediction vs. original value", typeof(BoolData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficient", "Theil's inequality coefficient of the model", typeof(DoubleData), VariableKind.New));
+
+    }
+
+    public override IOperation Apply(IScope scope) {
+      differential = GetVariableValue<BoolData>("Differential", scope, true).Data;
+      theilInequaliy = GetVariableValue<DoubleData>("TheilInequalityCoefficient", scope, false, false);
+      if(theilInequaliy == null) {
+        theilInequaliy = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficient"), theilInequaliy));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0.0;
+      double estimatedSquaredSum = 0.0;
+      double originalSquaredSum = 0.0;
+      for(int sample = start; sample < end; sample++) {
+        double prevValue = 0.0;
+        if(differential) prevValue = GetOriginalValue(sample - 1);
+        double estimatedChange = GetEstimatedValue(sample) - prevValue;
+        double originalChange = GetOriginalValue(sample) - prevValue;
+        SetOriginalValue(sample, estimatedChange + prevValue);
+        if(!double.IsNaN(originalChange) && !double.IsInfinity(originalChange)) {
+          double error = estimatedChange - originalChange;
+          errorsSquaredSum += error * error;
+          estimatedSquaredSum += estimatedChange * estimatedChange;
+          originalSquaredSum += originalChange * originalChange;
+        }
+      }
+      int nSamples = end - start;
+      double quality = Math.Sqrt(errorsSquaredSum / nSamples) / (Math.Sqrt(estimatedSquaredSum / nSamples) + Math.Sqrt(originalSquaredSum / nSamples));
+      if(double.IsNaN(quality) || double.IsInfinity(quality))
+        quality = double.MaxValue;
+      theilInequaliy.Data = quality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Addition.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Addition.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Addition.cs	(revision 656)
@@ -0,0 +1,50 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using System.Linq;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Addition : FunctionBase {
+    public override string Description {
+      get {
+        return @"Returns the sum of all sub-tree results.
+    (+ 3) => 3
+    (+ 2 3) => 5
+    (+ 3 4 5) => 12";
+      }
+    }
+
+    public Addition()
+      : base() {
+      // 2 - 3 seems like an reasonable defaut (used for +,-,*,/) (discussion with swinkler and maffenze)
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/And.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/And.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/And.cs	(revision 656)
@@ -0,0 +1,46 @@
+#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.Constraints;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class And : FunctionBase {
+    public override string Description {
+      get {
+        return @"Logical AND operation. Only defined for sub-tree-results 0.0 and 1.0.
+AND is a special form, sub-trees are evaluated from the first to the last. Evaluation is 
+stopped as soon as one of the sub-trees evaluates to 0.0 (false).";
+      }
+    }
+
+    public And()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Average.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Average.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Average.cs	(revision 656)
@@ -0,0 +1,44 @@
+#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.Constraints;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Average : FunctionBase {
+    public override string Description {
+      get {
+        return @"Returns the average (arithmetic mean) of all sub-tree results.";
+      }
+    }
+
+    public Average()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/BakedTreeEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/BakedTreeEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/BakedTreeEvaluator.cs	(revision 656)
@@ -0,0 +1,263 @@
+﻿#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.Core;
+using System.Xml;
+using System.Diagnostics;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class BakedTreeEvaluator {
+    private const int MAX_TREE_SIZE = 4096;
+    private const double EPSILON = 1.0e-7;
+
+    private class Instr {
+      public double d_arg0;
+      public int i_arg0;
+      public int i_arg1;
+      public int arity;
+      public int symbol;
+      public IFunction function;
+    }
+
+    private Instr[] codeArr;
+    private int PC;
+    private Dataset dataset;
+    private int sampleIndex;
+
+
+    public BakedTreeEvaluator() {
+      codeArr = new Instr[MAX_TREE_SIZE];
+      for(int i = 0; i < MAX_TREE_SIZE; i++) {
+        codeArr[i] = new Instr();
+      }
+    }
+
+    public void ResetEvaluator(BakedFunctionTree functionTree, Dataset dataset) {
+      this.dataset = dataset;
+      List<LightWeightFunction> linearRepresentation = functionTree.LinearRepresentation;
+      int i = 0;
+      foreach(LightWeightFunction f in linearRepresentation) {
+        TranslateToInstr(f, codeArr[i++]);
+      }
+    }
+
+    private Instr TranslateToInstr(LightWeightFunction f, Instr instr) {
+      instr.arity = f.arity;
+      instr.symbol = EvaluatorSymbolTable.MapFunction(f.functionType);
+      switch(instr.symbol) {
+        case EvaluatorSymbolTable.DIFFERENTIAL:
+        case EvaluatorSymbolTable.VARIABLE: {
+            instr.i_arg0 = (int)f.data[0]; // var
+            instr.d_arg0 = f.data[1]; // weight
+            instr.i_arg1 = (int)f.data[2]; // sample-offset
+            break;
+          }
+        case EvaluatorSymbolTable.CONSTANT: {
+            instr.d_arg0 = f.data[0]; // value
+            break;
+          }
+        case EvaluatorSymbolTable.UNKNOWN: {
+            instr.function = f.functionType;
+            break;
+          }
+      }
+      return instr;
+    }
+
+    public double Evaluate(int sampleIndex) {
+      PC = 0;
+      this.sampleIndex = sampleIndex;
+      return EvaluateBakedCode();
+    }
+
+    // skips a whole branch
+    private void SkipBakedCode() {
+      int i = 1;
+      while(i > 0) {
+        i += codeArr[PC++].arity;
+        i--;
+      }
+    }
+
+    private double EvaluateBakedCode() {
+      Instr currInstr = codeArr[PC++];
+      switch(currInstr.symbol) {
+        case EvaluatorSymbolTable.VARIABLE: {
+            int row = sampleIndex + currInstr.i_arg1;
+            if(row < 0 || row >= dataset.Rows) return double.NaN;
+            else return currInstr.d_arg0 * dataset.GetValue(row, currInstr.i_arg0);
+          }
+        case EvaluatorSymbolTable.CONSTANT: {
+            return currInstr.d_arg0;
+          }
+        case EvaluatorSymbolTable.DIFFERENTIAL: {
+            int row = sampleIndex + currInstr.i_arg1;
+            if(row < 1 || row >= dataset.Rows) return double.NaN;
+            else return currInstr.d_arg0 * (dataset.GetValue(row, currInstr.i_arg0) - dataset.GetValue(row - 1, currInstr.i_arg0));
+          }
+        case EvaluatorSymbolTable.MULTIPLICATION: {
+            double result = EvaluateBakedCode();
+            for(int i = 1; i < currInstr.arity; i++) {
+              result *= EvaluateBakedCode();
+            }
+            return result;
+          }
+        case EvaluatorSymbolTable.ADDITION: {
+            double sum = EvaluateBakedCode();
+            for(int i = 1; i < currInstr.arity; i++) {
+              sum += EvaluateBakedCode();
+            }
+            return sum;
+          }
+        case EvaluatorSymbolTable.SUBTRACTION: {
+            if(currInstr.arity == 1) {
+              return -EvaluateBakedCode();
+            } else {
+              double result = EvaluateBakedCode();
+              for(int i = 1; i < currInstr.arity; i++) {
+                result -= EvaluateBakedCode();
+              }
+              return result;
+            }
+          }
+        case EvaluatorSymbolTable.DIVISION: {
+            double result;
+            if(currInstr.arity == 1) {
+              result = 1.0 / EvaluateBakedCode();
+            } else {
+              result = EvaluateBakedCode();
+              for(int i = 1; i < currInstr.arity; i++) {
+                result /= EvaluateBakedCode();
+              }
+            }
+            if(double.IsInfinity(result)) return 0.0;
+            else return result;
+          }
+        case EvaluatorSymbolTable.AVERAGE: {
+            double sum = EvaluateBakedCode();
+            for(int i = 1; i < currInstr.arity; i++) {
+              sum += EvaluateBakedCode();
+            }
+            return sum / currInstr.arity;
+          }
+        case EvaluatorSymbolTable.COSINUS: {
+            return Math.Cos(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.SINUS: {
+            return Math.Sin(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.EXP: {
+            return Math.Exp(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.LOG: {
+            return Math.Log(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.POWER: {
+            double x = EvaluateBakedCode();
+            double p = EvaluateBakedCode();
+            return Math.Pow(x, p);
+          }
+        case EvaluatorSymbolTable.SIGNUM: {
+            double value = EvaluateBakedCode();
+            if(double.IsNaN(value)) return double.NaN;
+            else return Math.Sign(value);
+          }
+        case EvaluatorSymbolTable.SQRT: {
+            return Math.Sqrt(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.TANGENS: {
+            return Math.Tan(EvaluateBakedCode());
+          }
+        case EvaluatorSymbolTable.AND: { // only defined for inputs 1 and 0
+            double result = EvaluateBakedCode();
+            for(int i = 1; i < currInstr.arity; i++) {
+              if(result == 0.0) SkipBakedCode();
+              else {
+                result = EvaluateBakedCode();
+              }
+              Debug.Assert(result == 0.0 || result == 1.0);
+            }
+            return result;
+          }
+        case EvaluatorSymbolTable.EQU: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(Math.Abs(x - y) < EPSILON) return 1.0; else return 0.0;
+          }
+        case EvaluatorSymbolTable.GT: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(x > y) return 1.0;
+            else return 0.0;
+          }
+        case EvaluatorSymbolTable.IFTE: { // only defined for condition 0 or 1
+            double condition = EvaluateBakedCode();
+            Debug.Assert(condition == 0.0 || condition == 1.0);
+            double result;
+            if(condition == 0.0) {
+              result = EvaluateBakedCode(); SkipBakedCode();
+            } else {
+              SkipBakedCode(); result = EvaluateBakedCode();
+            }
+            return result;
+          }
+        case EvaluatorSymbolTable.LT: {
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            if(x < y) return 1.0;
+            else return 0.0;
+          }
+        case EvaluatorSymbolTable.NOT: { // only defined for inputs 0 or 1
+            double result = EvaluateBakedCode();
+            Debug.Assert(result == 0.0 || result == 1.0);
+            return Math.Abs(result - 1.0);
+          }
+        case EvaluatorSymbolTable.OR: { // only defined for inputs 0 or 1
+            double result = EvaluateBakedCode();
+            for(int i = 1; i < currInstr.arity; i++) {
+              if(result > 0.0) SkipBakedCode();
+              else {
+                result = EvaluateBakedCode();
+                Debug.Assert(result == 0.0 || result == 1.0);
+              }
+            }
+            return result;
+          }
+        case EvaluatorSymbolTable.XOR: { // only defined for inputs 0 or 1
+            double x = EvaluateBakedCode();
+            double y = EvaluateBakedCode();
+            return Math.Abs(x - y);
+          }
+        case EvaluatorSymbolTable.UNKNOWN: { // evaluate functions which are not statically defined directly
+            return currInstr.function.Apply();
+          }
+        default: {
+            throw new NotImplementedException();
+          }
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Constant.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Constant.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Constant.cs	(revision 656)
@@ -0,0 +1,93 @@
+#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.Text;
+using HeuristicLab.Data;
+using HeuristicLab.Core;
+using System.Xml;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Constant : FunctionBase {
+    public const string VALUE = "Value";
+
+    public override string Description {
+      get { return "Returns the value of local variable 'Value'."; }
+    }
+
+    public Constant()
+      : base() {
+      AddVariableInfo(new VariableInfo(VALUE, "The constant value", typeof(ConstrainedDoubleData), VariableKind.None));
+      GetVariableInfo(VALUE).Local = true;
+
+      ConstrainedDoubleData valueData = new ConstrainedDoubleData();
+      // initialize a default range for the contant value
+      valueData.AddConstraint(new DoubleBoundedConstraint(-20.0, 20.0));
+      HeuristicLab.Core.Variable value = new HeuristicLab.Core.Variable(VALUE, valueData);
+      AddVariable(value);
+
+      SetupInitialization();
+      SetupManipulation();
+
+      // constant can't have suboperators
+      AddConstraint(new NumberOfSubOperatorsConstraint(0, 0));
+    }
+
+    private void SetupInitialization() {
+      // initialization operator
+      AddVariableInfo(new VariableInfo(INITIALIZATION, "Initialization operator-graph for constants", typeof(IOperatorGraph), VariableKind.None));
+      GetVariableInfo(INITIALIZATION).Local = false;
+      CombinedOperator combinedOp = new CombinedOperator();
+      SequentialProcessor initSeq = new SequentialProcessor();
+      UniformRandomizer randomizer = new UniformRandomizer();
+      randomizer.Min = -20.0;
+      randomizer.Max = 20.0;
+
+      combinedOp.OperatorGraph.AddOperator(initSeq);
+      combinedOp.OperatorGraph.AddOperator(randomizer);
+      combinedOp.OperatorGraph.InitialOperator = initSeq;
+      initSeq.AddSubOperator(randomizer);
+      AddVariable(new HeuristicLab.Core.Variable(INITIALIZATION, combinedOp));
+    }
+
+    private void SetupManipulation() {
+      // manipulation operator
+      AddVariableInfo(new VariableInfo(MANIPULATION, "Manipulation operator-graph for constants", typeof(IOperatorGraph), VariableKind.None));
+      GetVariableInfo(MANIPULATION).Local = false;
+      CombinedOperator combinedOp = new CombinedOperator();
+      SequentialProcessor manipulationSeq = new SequentialProcessor();
+      NormalRandomAdder valueAdder = new NormalRandomAdder();
+      valueAdder.Mu = 0.0;
+      valueAdder.Sigma = 0.1;
+
+      combinedOp.OperatorGraph.AddOperator(manipulationSeq);
+      combinedOp.OperatorGraph.AddOperator(valueAdder);
+      combinedOp.OperatorGraph.InitialOperator = manipulationSeq;
+      manipulationSeq.AddSubOperator(valueAdder);
+      AddVariable(new HeuristicLab.Core.Variable(MANIPULATION, combinedOp));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Cosinus.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Cosinus.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Cosinus.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Cosinus : FunctionBase {
+    public override string Description {
+      get { return "Returns the cosinus of the first sub-tree."; }
+    }
+
+    public Cosinus()
+      : base() {
+      // must have exactly one subfunction
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Differential.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Differential.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Differential.cs	(revision 656)
@@ -0,0 +1,46 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Differential : Variable {
+
+    public override string Description {
+      get {
+        return @"Differential returns the difference between the value of a variable at t and t-1. The weight is a coefficient that is multiplied to the the difference.";
+      }
+    }
+
+    public Differential()
+      : base() {
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Division.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Division.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Division.cs	(revision 656)
@@ -0,0 +1,57 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using System.Linq;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Division : FunctionBase {
+    private const double EPSILON = 10.0E-20; // if any divisor is < EPSILON return 0
+
+    public override string Description {
+      get {
+        return @"Protected division
+Divides the result of the first sub-tree by the results of the following sub-tree.
+In case one of the divisors is 0 returns 0.
+    (/ 3) => 1/3
+    (/ 2 3) => 2/3
+    (/ 3 4 5) => 3/20
+    (/ 2 0 4) => 0
+";
+      }
+    }
+
+    public Division()
+      : base() {
+      // 2 - 3 seems like an reasonable defaut (used for +,-,*,/) (discussion with swinkler and maffenze)
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Equal.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Equal.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Equal.cs	(revision 656)
@@ -0,0 +1,44 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Equal : FunctionBase {
+    public override string Description {
+      get {
+        return @"Equal condition. Returns 1.0 if both sub-trees evaluate to the same value and 0.0 if they differ.";
+      }
+    }
+
+    public Equal()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/CoefficientOfDeterminationEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/CoefficientOfDeterminationEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/CoefficientOfDeterminationEvaluator.cs	(revision 656)
@@ -0,0 +1,79 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class CoefficientOfDeterminationEvaluator : GPEvaluatorBase {
+    private DoubleData r2;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'Dataset' and calculates
+the 'coefficient of determination' of estimated values vs. real values of 'TargetVariable'.";
+      }
+    }
+
+    public CoefficientOfDeterminationEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("R2", "The coefficient of determination of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      r2 = GetVariableValue<DoubleData>("R2", scope, false, false);
+      if(r2 == null) {
+        r2 = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("R2"), r2));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0.0;
+      double originalDeviationTotalSumOfSquares = 0.0;
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          double error = estimated - original;
+          errorsSquaredSum += error * error;
+
+          double origDeviation = original - TargetMean;
+          originalDeviationTotalSumOfSquares += origDeviation * origDeviation;
+        }
+      }
+
+      double quality = 1 - errorsSquaredSum / originalDeviationTotalSumOfSquares;
+      if(quality > 1)
+        throw new InvalidProgramException();
+      if(double.IsNaN(quality) || double.IsInfinity(quality))
+        quality = double.MaxValue;
+      r2.Data = quality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/EarlyStoppingMeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/EarlyStoppingMeanSquaredErrorEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/EarlyStoppingMeanSquaredErrorEvaluator.cs	(revision 656)
@@ -0,0 +1,76 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class EarlyStoppingMeanSquaredErrorEvaluator : MeanSquaredErrorEvaluator {
+    private double qualityLimit;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of the dataset and calculates the mean-squared-error
+for the estimated values vs. the real values of 'TargetVariable'.
+This operator stops the computation as soon as an upper limit for the mean-squared-error is reached.";
+      }
+    }
+
+    public EarlyStoppingMeanSquaredErrorEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("QualityLimit", "The upper limit of the MSE which is used as early stopping criterion.", typeof(DoubleData), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      qualityLimit = GetVariableValue<DoubleData>("QualityLimit", scope, false).Data;
+      return base.Apply(scope);
+    }
+
+    // evaluates the function-tree for the given target-variable and the whole dataset and returns the MSE
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0;
+      int rows = end - start;
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          double error = estimated - original;
+          errorsSquaredSum += error * error;
+        }
+        // check the limit and stop as soon as we hit the limit
+        if(errorsSquaredSum / rows >= qualityLimit) {
+          mse.Data = errorsSquaredSum / (sample - start + 1); // return estimated MSE (when the remaining errors are on average the same)
+          return;
+        }
+      }
+      errorsSquaredSum /= rows;
+      if(double.IsNaN(errorsSquaredSum) || double.IsInfinity(errorsSquaredSum)) {
+        errorsSquaredSum = double.MaxValue;
+      }
+      mse.Data = errorsSquaredSum;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/GPEvaluatorBase.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/GPEvaluatorBase.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/GPEvaluatorBase.cs	(revision 656)
@@ -0,0 +1,132 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public abstract class GPEvaluatorBase : OperatorBase {
+    private int targetVariable;
+    private int start;
+    private int end;
+    private bool useEstimatedValues;
+    private double[] backupValues;
+    private int evaluatedSamples;
+    private double estimatedValueMax;
+    private double estimatedValueMin;
+    private int treeSize;
+    private double totalEvaluatedNodes;
+    protected Dataset dataset;
+    private double targetMean;
+    private BakedTreeEvaluator evaluator;
+    protected double TargetMean { get { return targetMean; } }
+
+    public GPEvaluatorBase()
+      : base() {
+      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be evaluated", typeof(IFunctionTree), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TreeSize", "Size (number of nodes) of the tree to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Dataset", "Dataset with all samples on which to apply the function", typeof(Dataset), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TargetVariable", "Index of the column of the dataset that holds the target variable", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("PunishmentFactor", "Punishment factor for invalid estimations", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("TotalEvaluatedNodes", "Number of evaluated nodes", typeof(DoubleData), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("SamplesStart", "Start index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("SamplesEnd", "End index of samples in dataset to evaluate", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("UseEstimatedTargetValue", "Wether to use the original (measured) or the estimated (calculated) value for the targat variable when doing autoregressive modelling", typeof(BoolData), VariableKind.In));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      // get all variable values
+      targetVariable = GetVariableValue<IntData>("TargetVariable", scope, true).Data;
+      dataset = GetVariableValue<Dataset>("Dataset", scope, true);
+      BakedFunctionTree functionTree = GetVariableValue<BakedFunctionTree>("FunctionTree", scope, true);
+      double maximumPunishment = GetVariableValue<DoubleData>("PunishmentFactor", scope, true).Data * dataset.GetRange(targetVariable);
+      treeSize = scope.GetVariableValue<IntData>("TreeSize", false).Data;
+      totalEvaluatedNodes = scope.GetVariableValue<DoubleData>("TotalEvaluatedNodes", true).Data;
+      int start = GetVariableValue<IntData>("SamplesStart", scope, true).Data;
+      int end = GetVariableValue<IntData>("SamplesEnd", scope, true).Data;
+      useEstimatedValues = GetVariableValue<BoolData>("UseEstimatedTargetValue", scope, true).Data;
+      // prepare for autoregressive modelling by saving the original values of the target-variable to a backup array
+      if(useEstimatedValues &&
+        (backupValues == null || start != this.start || end != this.end)) {
+        this.start = start;
+        this.end = end;
+        backupValues = new double[end - start];
+        for(int i = start; i < end; i++) {
+          backupValues[i - start] = dataset.GetValue(i, targetVariable);
+        }
+      }
+      // get the mean of the values of the target variable to determin the max and min bounds of the estimated value
+      targetMean = dataset.GetMean(targetVariable, start, end - 1);
+      estimatedValueMin = targetMean - maximumPunishment;
+      estimatedValueMax = targetMean + maximumPunishment;
+
+      // initialize and reset the evaluator
+      if(evaluator == null) evaluator = new BakedTreeEvaluator();
+      evaluator.ResetEvaluator(functionTree, dataset);
+      evaluatedSamples = 0;
+
+      Evaluate(start, end);
+
+      // restore the values of the target variable from the backup array if necessary
+      if(useEstimatedValues) RestoreDataset(dataset, targetVariable, start, end);
+      // update the value of total evaluated nodes
+      scope.GetVariableValue<DoubleData>("TotalEvaluatedNodes", true).Data = totalEvaluatedNodes + treeSize * evaluatedSamples;
+      return null;
+    }
+
+    private void RestoreDataset(Dataset dataset, int targetVariable, int from, int to) {
+      for(int i = from; i < to; i++) {
+        dataset.SetValue(i, targetVariable, backupValues[i - from]);
+      }
+    }
+
+    public abstract void Evaluate(int start, int end);
+
+    public void SetOriginalValue(int sample, double value) {
+      if(useEstimatedValues) {
+        dataset.SetValue(sample, targetVariable, value);
+      }
+    }
+
+    public double GetOriginalValue(int sample) {
+      return dataset.GetValue(sample, targetVariable);
+    }
+
+    public double GetEstimatedValue(int sample) {
+      evaluatedSamples++;
+      double estimated = evaluator.Evaluate(sample);
+      if(double.IsNaN(estimated) || double.IsInfinity(estimated)) {
+        estimated = estimatedValueMax;
+      } else if(estimated > estimatedValueMax) {
+        estimated = estimatedValueMax;
+      } else if(estimated < estimatedValueMin) {
+        estimated = estimatedValueMin;
+      }
+      return estimated;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanAbsolutePercentageErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanAbsolutePercentageErrorEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanAbsolutePercentageErrorEvaluator.cs	(revision 656)
@@ -0,0 +1,74 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class MeanAbsolutePercentageErrorEvaluator : GPEvaluatorBase {
+    private DoubleData mape;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'Dataset' and calculates
+the 'mean absolute percentage error (scale invariant)' of estimated values vs. real values of 'TargetVariable'.";
+      }
+    }
+
+    public MeanAbsolutePercentageErrorEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("MAPE", "The mean absolute percentage error of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      mape = GetVariableValue<DoubleData>("MAPE", scope, false, false);
+      if(mape == null) {
+        mape = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("MAPE"), mape));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSum = 0.0;
+      int n = 0;
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original) && original!=0.0) {
+          double percent_error = Math.Abs((estimated - original) / original);
+          errorsSum += percent_error;
+          n++;
+        }
+      }
+      double quality = errorsSum / n;
+      if(double.IsNaN(quality) || double.IsInfinity(quality))
+        quality = double.MaxValue;
+      mape.Data = quality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanSquaredErrorEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanSquaredErrorEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/MeanSquaredErrorEvaluator.cs	(revision 656)
@@ -0,0 +1,74 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class MeanSquaredErrorEvaluator : GPEvaluatorBase {
+    protected DoubleData mse;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'DataSet' and calculates the mean-squared-error
+for the estimated values vs. the real values of 'TargetVariable'.";
+      }
+    }
+
+    public MeanSquaredErrorEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("MSE", "The mean squared error of the model", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      mse = GetVariableValue<DoubleData>("MSE", scope, false, false);
+      if(mse == null) {
+        mse = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("MSE"), mse));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      double errorsSquaredSum = 0;
+      for(int sample = start; sample < end; sample++) {
+        double original = GetOriginalValue(sample);
+        double estimated = GetEstimatedValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          double error = estimated - original;
+          errorsSquaredSum += error * error;
+        }
+      }
+
+      errorsSquaredSum /= (end - start);
+      if(double.IsNaN(errorsSquaredSum) || double.IsInfinity(errorsSquaredSum)) {
+        errorsSquaredSum = double.MaxValue;
+      }
+      mse.Data = errorsSquaredSum;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/SimpleEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/SimpleEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/SimpleEvaluator.cs	(revision 656)
@@ -0,0 +1,64 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class SimpleEvaluator : GPEvaluatorBase {
+    private ItemList values;
+    public SimpleEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Values", "The values of the target variable as predicted by the model and the original value of the target variable", typeof(ItemList), VariableKind.New | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      values = GetVariableValue<ItemList>("Values", scope, false, false);
+      if(values == null) {
+        values = new ItemList();
+        IVariableInfo info = GetVariableInfo("Values");
+        if(info.Local)
+          AddVariable(new HeuristicLab.Core.Variable(info.ActualName, values));
+        else
+          scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName(info.FormalName), values));
+      }
+      values.Clear();
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      for(int sample = start; sample < end; sample++) {
+        ItemList row = new ItemList();
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        row.Add(new DoubleData(estimated));
+        row.Add(new DoubleData(original));
+        values.Add(row);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/VarianceAccountedForEvaluator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/VarianceAccountedForEvaluator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Evaluators/VarianceAccountedForEvaluator.cs	(revision 656)
@@ -0,0 +1,89 @@
+#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.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class VarianceAccountedForEvaluator : GPEvaluatorBase {
+    private DoubleData vaf;
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'DataSet' and calculates 
+the variance-accounted-for quality measure for the estimated values vs. the real values of 'TargetVariable'.
+
+The Variance Accounted For (VAF) function is computed as
+VAF(y,y') = ( 1 - var(y-y')/var(y) )
+where y' denotes the predicted / modelled values for y and var(x) the variance of a signal x.";
+      }
+    }
+
+    /// <summary>
+    /// The Variance Accounted For (VAF) function calculates is computed as
+    /// VAF(y,y') = ( 1 - var(y-y')/var(y) )
+    /// where y' denotes the predicted / modelled values for y and var(x) the variance of a signal x.
+    /// </summary>
+    public VarianceAccountedForEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("VAF", "The variance-accounted-for quality of the model", typeof(DoubleData), VariableKind.New));
+
+    }
+
+    public override IOperation Apply(IScope scope) {
+      vaf = GetVariableValue<DoubleData>("VAF", scope, false, false);
+      if(vaf == null) {
+        vaf = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("VAF"), vaf));
+      }
+
+      return base.Apply(scope);
+    }
+
+    public override void Evaluate(int start, int end) {
+      int nSamples = end - start;
+      double[] errors = new double[nSamples];
+      double[] originalTargetVariableValues = new double[nSamples];
+      for(int sample = start; sample < end; sample++) {
+        double estimated = GetEstimatedValue(sample);
+        double original = GetOriginalValue(sample);
+        SetOriginalValue(sample, estimated);
+        if(!double.IsNaN(original) && !double.IsInfinity(original)) {
+          errors[sample - start] = original - estimated;
+          originalTargetVariableValues[sample - start] = original;
+        }
+      }
+      double errorsVariance = Statistics.Variance(errors);
+      double originalsVariance = Statistics.Variance(originalTargetVariableValues);
+      double quality = 1 - errorsVariance / originalsVariance;
+
+      if(double.IsNaN(quality) || double.IsInfinity(quality)) {
+        quality = double.MaxValue;
+      }
+      vaf.Data = quality;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Exponential.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Exponential.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Exponential.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Exponential : FunctionBase {
+    public override string Description {
+      get { return "Returns returns exponential of the first sub-tree (power(e, x))."; }
+    }
+
+    public Exponential()
+      : base() {
+      // must have exactly one sub-operator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/GreaterThan.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/GreaterThan.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/GreaterThan.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Constraints;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class GreaterThan : FunctionBase {
+    public override string Description {
+      get {
+        return @"Greater-than condition. Returns 1.0 if the value of the first sub-tree is greater than the value of the second sub-tree and 0.0 otherwise.";
+      }
+    }
+
+    public GreaterThan()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj	(revision 656)
@@ -0,0 +1,168 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<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.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{74223A32-C726-4978-BE78-37113A18373C}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.StructureIdentification</RootNamespace>
+    <AssemblyName>HeuristicLab.GP.StructureIdentification-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </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="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Addition.cs" />
+    <Compile Include="And.cs" />
+    <Compile Include="Average.cs" />
+    <Compile Include="BakedTreeEvaluator.cs" />
+    <Compile Include="Constant.cs" />
+    <Compile Include="Cosinus.cs" />
+    <Compile Include="Differential.cs" />
+    <Compile Include="Division.cs" />
+    <Compile Include="Equal.cs" />
+    <Compile Include="Evaluators\CoefficientOfDeterminationEvaluator.cs" />
+    <Compile Include="Evaluators\EarlyStoppingMeanSquaredErrorEvaluator.cs" />
+    <Compile Include="Evaluators\GPEvaluatorBase.cs" />
+    <Compile Include="Evaluators\MeanAbsolutePercentageErrorEvaluator.cs" />
+    <Compile Include="Evaluators\MeanSquaredErrorEvaluator.cs" />
+    <Compile Include="Evaluators\SimpleEvaluator.cs" />
+    <Compile Include="Evaluators\VarianceAccountedForEvaluator.cs" />
+    <Compile Include="Exponential.cs" />
+    <Compile Include="GreaterThan.cs" />
+    <Compile Include="HeuristicLabGPStructureIdentificationPlugin.cs" />
+    <Compile Include="IfThenElse.cs" />
+    <Compile Include="LessThan.cs" />
+    <Compile Include="Logarithm.cs" />
+    <Compile Include="ModelAnalyzerExporter.cs" />
+    <Compile Include="Multiplication.cs" />
+    <Compile Include="Not.cs" />
+    <Compile Include="Or.cs" />
+    <Compile Include="Power.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Signum.cs" />
+    <Compile Include="Sinus.cs" />
+    <Compile Include="Sqrt.cs" />
+    <Compile Include="StructIdProblemInjector.cs" />
+    <Compile Include="StructIdProblemInjectorView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="StructIdProblemInjectorView.Designer.cs">
+      <DependentUpon>StructIdProblemInjectorView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Subtraction.cs" />
+    <Compile Include="SymbolicExpressionExporter.cs" />
+    <Compile Include="SymbolTable.cs" />
+    <Compile Include="Tangens.cs" />
+    <Compile Include="Variable.cs" />
+    <Compile Include="Xor.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.DataAnalysis\HeuristicLab.DataAnalysis.csproj">
+      <Project>{7DD3A97A-56E9-462F-90E2-A351FE7AF5C2}</Project>
+      <Name>HeuristicLab.DataAnalysis</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.GP\HeuristicLab.GP.csproj">
+      <Project>{1F1CF3ED-374C-4288-995B-93F6B872F571}</Project>
+      <Name>HeuristicLab.GP</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Operators\HeuristicLab.Operators.csproj">
+      <Project>{A9983BA2-B3B2-475E-8E2C-62050B71D1C5}</Project>
+      <Name>HeuristicLab.Operators</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Random\HeuristicLab.Random.csproj">
+      <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
+      <Name>HeuristicLab.Random</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="StructIdProblemInjectorView.resx">
+      <DependentUpon>StructIdProblemInjectorView.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </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>cmd /c ""$(SolutionDir)PreBuildEvent.cmd" "$(ProjectDir).""</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLabGPStructureIdentificationPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLabGPStructureIdentificationPlugin.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/HeuristicLabGPStructureIdentificationPlugin.cs	(revision 656)
@@ -0,0 +1,39 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  [ClassInfo(Name = "HeuristicLab.GP.StructureIdentification-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP.StructureIdentification-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.DataAnalysis-3.2")]
+  [Dependency(Dependency = "HeuristicLab.GP-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  public class HeuristicLabGPStructureIdentificationPlugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/IfThenElse.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/IfThenElse.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/IfThenElse.cs	(revision 656)
@@ -0,0 +1,46 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class IfThenElse : FunctionBase {
+    public override string Description {
+      get {
+        return @"Returns the result of the second sub-tree if the first sub-tree evaluates to a value < 0.5 and the result
+of the third sub-tree if the first sub-tree evaluates to >= 0.5.";
+      }
+    }
+
+    public IfThenElse()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(3, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/LessThan.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/LessThan.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/LessThan.cs	(revision 656)
@@ -0,0 +1,44 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class LessThan : FunctionBase {
+    public override string Description {
+      get {
+        return @"Less-than condition. Returns 1.0 if the value of the first sub-tree is less than the value of the second sub-tree and 0.0 otherwise.";
+      }
+    }
+
+    public LessThan()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Logarithm.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Logarithm.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Logarithm.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Logarithm : FunctionBase {
+    public override string Description {
+      get { return "Returns the natural (base e) logarithm of the first sub-tree."; }
+    }
+
+    public Logarithm()
+      : base() {
+      // must have exactly 1 suboperator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/ModelAnalyzerExporter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/ModelAnalyzerExporter.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/ModelAnalyzerExporter.cs	(revision 656)
@@ -0,0 +1,221 @@
+﻿#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.Data;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class ModelAnalyzerExporter : IFunctionTreeExporter, IFunctionTreeNameGenerator {
+    #region IFunctionTreeExporter Members
+
+    public string Name {
+      get {
+        return "HL2 ModelAnalyzer Exporter";
+      }
+    }
+
+    public bool TryExport(IFunctionTree tree, out string exported) {
+      try {
+        exported = Export(tree);
+        return true;
+      } catch(UnknownFunctionException) {
+        exported = "";
+        return false;
+      }
+    }
+
+    public string Export(IFunctionTree tree) {
+      string result = ExportFunction(tree.Function, tree);
+      result += "(\n";
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        result += Export(subTree);
+        result += ";\n";
+      }
+      result = result.TrimEnd(';', '\n');
+      if(tree.SubTrees.Count > 0) result += ")";
+      return result;
+    }
+
+    #endregion
+
+    private string ExportFunction(IFunction function, IFunctionTree tree) {
+      // this is smelly, if there is a cleaner way to have a 'dynamic' visitor 
+      // please let me know! (gkronber 14.10.2008)
+      if(function is Addition) return ((Addition)function).ExportToHL2(tree);
+      if(function is And) return ((And)function).ExportToHL2(tree);
+      if(function is Average) return ((Average)function).ExportToHL2(tree);
+      if(function is Constant) return ((Constant)function).ExportToHL2(tree);
+      if(function is Cosinus) return ((Cosinus)function).ExportToHL2(tree);
+      if(function is Differential) return ((Differential)function).ExportToHL2(tree);
+      if(function is Division) return ((Division)function).ExportToHL2(tree);
+      if(function is Equal) return ((Equal)function).ExportToHL2(tree);
+      if(function is Exponential) return ((Exponential)function).ExportToHL2(tree);
+      if(function is GreaterThan) return ((GreaterThan)function).ExportToHL2(tree);
+      if(function is IfThenElse) return ((IfThenElse)function).ExportToHL2(tree);
+      if(function is LessThan) return ((LessThan)function).ExportToHL2(tree);
+      if(function is Logarithm) return ((Logarithm)function).ExportToHL2(tree);
+      if(function is Multiplication) return ((Multiplication)function).ExportToHL2(tree);
+      if(function is Not) return ((Not)function).ExportToHL2(tree);
+      if(function is Or) return ((Or)function).ExportToHL2(tree);
+      if(function is Power) return ((Power)function).ExportToHL2(tree);
+      if(function is Signum) return ((Signum)function).ExportToHL2(tree);
+      if(function is Sinus) return ((Sinus)function).ExportToHL2(tree);
+      if(function is Sqrt) return ((Sqrt)function).ExportToHL2(tree);
+      if(function is Subtraction) return ((Subtraction)function).ExportToHL2(tree);
+      if(function is Tangens) return ((Tangens)function).ExportToHL2(tree);
+      if(function is Variable) return ((Variable)function).ExportToHL2(tree);
+      if(function is Xor) return ((Xor)function).ExportToHL2(tree);
+      throw new UnknownFunctionException(function.Name);
+    }
+
+    #region IFunctionTreeNameGenerator Members
+
+    string IFunctionTreeNameGenerator.Name {
+      get { return "HL2 Representation"; }
+    }
+
+    public string GetName(IFunctionTree tree) {
+      string name = "";
+      try {
+        name = ExportFunction(tree.Function, tree);
+      } catch(UnknownFunctionException) {
+        name = "N/A";
+      }
+      return name;
+    }
+
+    #endregion
+  }
+
+  internal static class HL2ExporterExtensions {
+    private static string GetHL2FunctionName(string name) {
+      return "[F]" + name ;
+    }
+
+    public static string ExportToHL2(this Addition addition, IFunctionTree tree) {
+      return GetHL2FunctionName("Addition[0]");
+    }
+
+    public static string ExportToHL2(this Constant constant, IFunctionTree tree) {
+      double value = ((ConstrainedDoubleData)tree.GetLocalVariable(Constant.VALUE).Value).Data;
+      return "[T]Constant(" + value.ToString("r") + ";0;0)";
+    }
+
+    public static string ExportToHL2(this Cosinus cosinus, IFunctionTree tree) {
+      return GetHL2FunctionName("Trigonometrics[1]");
+    }
+
+    public static string ExportToHL2(this Differential differential, IFunctionTree tree) {
+      double weight = ((ConstrainedDoubleData)tree.GetLocalVariable(Differential.WEIGHT).Value).Data;
+      double index = ((ConstrainedIntData)tree.GetLocalVariable(Differential.INDEX).Value).Data;
+      double offset = ((ConstrainedIntData)tree.GetLocalVariable(Differential.OFFSET).Value).Data;
+
+      return "[T]Differential(" + weight.ToString("r") + ";" + index + ";" + -offset + ")";
+    }
+
+    public static string ExportToHL2(this Division division, IFunctionTree tree) {
+      return GetHL2FunctionName("Division[0]");
+    }
+
+    public static string ExportToHL2(this Exponential exponential, IFunctionTree tree) {
+      return GetHL2FunctionName("Exponential[0]");
+    }
+
+    public static string ExportToHL2(this Logarithm logarithm, IFunctionTree tree) {
+      return GetHL2FunctionName("Logarithm[0]");
+    }
+
+    public static string ExportToHL2(this Multiplication multiplication, IFunctionTree tree) {
+      return GetHL2FunctionName("Multiplication[0]");
+    }
+
+    public static string ExportToHL2(this Power power, IFunctionTree tree) {
+      return GetHL2FunctionName("Power[0]");
+    }
+
+    public static string ExportToHL2(this Signum signum, IFunctionTree tree) {
+      return GetHL2FunctionName("Signum[0]");
+    }
+
+    public static string ExportToHL2(this Sinus sinus, IFunctionTree tree) {
+      return GetHL2FunctionName("Trigonometrics[0]");
+    }
+
+    public static string ExportToHL2(this Sqrt sqrt, IFunctionTree tree) {
+      return GetHL2FunctionName("Sqrt[0]");
+    }
+
+    public static string ExportToHL2(this Subtraction substraction, IFunctionTree tree) {
+      return GetHL2FunctionName("Subtraction[0]");
+    }
+
+    public static string ExportToHL2(this Tangens tangens, IFunctionTree tree) {
+      return GetHL2FunctionName("Trigonometrics[2]");
+    }
+
+    public static string ExportToHL2(this Variable variable, IFunctionTree tree) {
+      double weight = ((ConstrainedDoubleData)tree.GetLocalVariable(Variable.WEIGHT).Value).Data;
+      double index = ((ConstrainedIntData)tree.GetLocalVariable(Variable.INDEX).Value).Data;
+      double offset = ((ConstrainedIntData)tree.GetLocalVariable(Variable.OFFSET).Value).Data;
+
+      return "[T]Variable(" + weight.ToString("r") + ";" + index + ";" + -offset + ")";
+    }
+
+    public static string ExportToHL2(this And and, IFunctionTree tree) {
+      return GetHL2FunctionName("Logical[0]");
+    }
+
+    public static string ExportToHL2(this Average average, IFunctionTree tree) {
+      return GetHL2FunctionName("Average[0]");
+    }
+
+    public static string ExportToHL2(this IfThenElse ifThenElse, IFunctionTree tree) {
+      return GetHL2FunctionName("Conditional[0]");
+    }
+
+    public static string ExportToHL2(this Not not, IFunctionTree tree) {
+      return GetHL2FunctionName("Logical[2]");
+    }
+
+    public static string ExportToHL2(this Or or, IFunctionTree tree) {
+      return GetHL2FunctionName("Logical[1]");
+    }
+
+    public static string ExportToHL2(this Xor xor, IFunctionTree tree) {
+      return GetHL2FunctionName("Logical[3]");
+    }
+
+    public static string ExportToHL2(this Equal equal, IFunctionTree tree) {
+      return GetHL2FunctionName("Boolean[2]");
+    }
+
+    public static string ExportToHL2(this LessThan lessThan, IFunctionTree tree) {
+      return GetHL2FunctionName("Boolean[0]");
+    }
+
+    public static string ExportToHL2(this GreaterThan greaterThan, IFunctionTree tree) {
+      return GetHL2FunctionName("Boolean[4]");
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Multiplication.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Multiplication.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Multiplication.cs	(revision 656)
@@ -0,0 +1,51 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using System.Linq;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Multiplication : FunctionBase {
+    public override string Description {
+      get {
+        return @"Returns the product of the results of all sub-tree.
+  (* 3) => 3
+  (* 2 3) => 6
+  (* 3 4 5) => 60";
+      }
+    }
+
+    public Multiplication()
+      : base() {
+      // 2 - 3 seems like an reasonable defaut (used for +,-,*,/) (discussion with swinkler and maffenze)
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Not.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Not.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Not.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Not : FunctionBase {
+    public override string Description {
+      get {
+        return @"Logical NOT operation. Only defined for sub-tree-results 0.0 and 1.0.";
+      }
+    }
+
+    public Not()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Or.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Or.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Or.cs	(revision 656)
@@ -0,0 +1,46 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Or : FunctionBase {
+    public override string Description {
+      get {
+        return @"Logical OR operation. Only defined for sub-tree-results 0.0 and 1.0.
+Special form, evaluation stops at first sub-tree that evaluates to 1.0 (true).";
+      }
+    }
+
+    public Or()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Power.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Power.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Power.cs	(revision 656)
@@ -0,0 +1,44 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Power : FunctionBase {
+    public override string Description {
+      get { return "Returns the result of the first sub-tree to the power of the second sub-tree (power(x, y))."; }
+    }
+
+    public Power()
+      : base() {
+      // must have exactly 2 suboperators base ^ exponent
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Properties/AssemblyInfo.frame	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Properties/AssemblyInfo.frame	(revision 656)
@@ -0,0 +1,58 @@
+#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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.StructureIdentification")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2008 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("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// 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.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Signum.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Signum.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Signum.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Signum : FunctionBase {
+    public override string Description {
+      get { return "Returns the signum of the first sub-tree."; }
+    }
+
+    public Signum()
+      : base() {
+      // must have exactly 1 suboperator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Sinus.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Sinus.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Sinus.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Sinus : FunctionBase {
+    public override string Description {
+      get { return "Returns the sinus of the first sub-tree."; }
+    }
+
+    public Sinus()
+      : base() {
+      // must have exactly 1 suboperator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Sqrt.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Sqrt.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Sqrt.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Sqrt : FunctionBase {
+    public override string Description {
+      get { return "Returns the square root of the first sub-tree."; }
+    }
+
+    public Sqrt()
+      : base() {
+      // must have exactly 1 suboperator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjector.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjector.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjector.cs	(revision 656)
@@ -0,0 +1,90 @@
+#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.Text;
+using System.Xml;
+using Core = HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class StructIdProblemInjector : Core.OperatorBase {
+    public override string Description {
+      get { return @"Injects the necessary variables for a structure identification problem."; }
+    }
+
+    public StructIdProblemInjector()
+      : base() {
+      AddVariableInfo(new Core.VariableInfo("Dataset", "Dataset", typeof(Dataset), Core.VariableKind.New));
+      GetVariableInfo("Dataset").Local = true;
+      AddVariable(new Core.Variable("Dataset", new Dataset()));
+
+      AddVariableInfo(new Core.VariableInfo("TargetVariable", "TargetVariable", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("TargetVariable").Local = true;
+      AddVariable(new Core.Variable("TargetVariable", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("AllowedFeatures", "Indexes of allowed input variables", typeof(ItemList<IntData>), Core.VariableKind.New));
+      GetVariableInfo("AllowedFeatures").Local = true;
+      AddVariable(new Core.Variable("AllowedFeatures", new ItemList<IntData>()));
+
+      AddVariableInfo(new Core.VariableInfo("TrainingSamplesStart", "TrainingSamplesStart", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("TrainingSamplesStart").Local = true;
+      AddVariable(new Core.Variable("TrainingSamplesStart", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("TrainingSamplesEnd", "TrainingSamplesEnd", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("TrainingSamplesEnd").Local = true;
+      AddVariable(new Core.Variable("TrainingSamplesEnd", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("ValidationSamplesStart", "ValidationSamplesStart", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("ValidationSamplesStart").Local = true;
+      AddVariable(new Core.Variable("ValidationSamplesStart", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("ValidationSamplesEnd", "ValidationSamplesEnd", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("ValidationSamplesEnd").Local = true;
+      AddVariable(new Core.Variable("ValidationSamplesEnd", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("TestSamplesStart", "TestSamplesStart", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("TestSamplesStart").Local = true;
+      AddVariable(new Core.Variable("TestSamplesStart", new IntData()));
+
+      AddVariableInfo(new Core.VariableInfo("TestSamplesEnd", "TestSamplesEnd", typeof(IntData), Core.VariableKind.New));
+      GetVariableInfo("TestSamplesEnd").Local = true;
+      AddVariable(new Core.Variable("TestSamplesEnd", new IntData()));
+    }
+
+    public override Core.IView CreateView() {
+      return new StructIdProblemInjectorView(this);
+    }
+
+    public override Core.IOperation Apply(Core.IScope scope) {
+      foreach(Core.VariableInfo info in VariableInfos) {
+        if(info.Local) {
+          Core.IVariable var = GetVariable(info.FormalName);
+          if(var != null) scope.AddVariable(new Core.Variable(info.ActualName, (Core.IItem)var.Value.Clone()));
+        }
+      }
+      return null;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.Designer.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.Designer.cs	(revision 656)
@@ -0,0 +1,213 @@
+#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
+
+namespace HeuristicLab.GP.StructureIdentification {
+  partial class StructIdProblemInjectorView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.importInstanceButton = new System.Windows.Forms.Button();
+      this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.dataTabPage = new System.Windows.Forms.TabPage();
+      this.datasetView = new HeuristicLab.DataAnalysis.DatasetView();
+      this.variableInfosTabPage = new System.Windows.Forms.TabPage();
+      this.operatorBaseVariableInfosView = new HeuristicLab.Core.OperatorBaseVariableInfosView();
+      this.tabPage1 = new System.Windows.Forms.TabPage();
+      this.variablesView = new HeuristicLab.Core.OperatorBaseVariablesView();
+      this.descriptionTabPage = new System.Windows.Forms.TabPage();
+      this.operatorBaseDescriptionView = new HeuristicLab.Core.OperatorBaseDescriptionView();
+      this.tabControl.SuspendLayout();
+      this.dataTabPage.SuspendLayout();
+      this.variableInfosTabPage.SuspendLayout();
+      this.tabPage1.SuspendLayout();
+      this.descriptionTabPage.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // importInstanceButton
+      // 
+      this.importInstanceButton.Location = new System.Drawing.Point(6, 6);
+      this.importInstanceButton.Name = "importInstanceButton";
+      this.importInstanceButton.Size = new System.Drawing.Size(129, 21);
+      this.importInstanceButton.TabIndex = 6;
+      this.importInstanceButton.Text = "&Import...";
+      this.importInstanceButton.UseVisualStyleBackColor = true;
+      this.importInstanceButton.Click += new System.EventHandler(this.importInstanceButton_Click);
+      // 
+      // openFileDialog
+      // 
+      this.openFileDialog.DefaultExt = "txt";
+      this.openFileDialog.FileName = "txt";
+      this.openFileDialog.Filter = "Text files|*.txt|All files|*.*";
+      this.openFileDialog.Title = "Import StructId File";
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.dataTabPage);
+      this.tabControl.Controls.Add(this.variableInfosTabPage);
+      this.tabControl.Controls.Add(this.tabPage1);
+      this.tabControl.Controls.Add(this.descriptionTabPage);
+      this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tabControl.Location = new System.Drawing.Point(0, 0);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(507, 451);
+      this.tabControl.TabIndex = 0;
+      // 
+      // dataTabPage
+      // 
+      this.dataTabPage.Controls.Add(this.datasetView);
+      this.dataTabPage.Controls.Add(this.importInstanceButton);
+      this.dataTabPage.Location = new System.Drawing.Point(4, 22);
+      this.dataTabPage.Name = "dataTabPage";
+      this.dataTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.dataTabPage.Size = new System.Drawing.Size(499, 425);
+      this.dataTabPage.TabIndex = 0;
+      this.dataTabPage.Text = "Data";
+      this.dataTabPage.UseVisualStyleBackColor = true;
+      // 
+      // datasetView
+      // 
+      this.datasetView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.datasetView.Caption = "Editor";
+      this.datasetView.Dataset = null;
+      this.datasetView.Filename = null;
+      this.datasetView.Location = new System.Drawing.Point(6, 33);
+      this.datasetView.Name = "datasetView";
+      this.datasetView.Size = new System.Drawing.Size(487, 386);
+      this.datasetView.TabIndex = 7;
+      // 
+      // variableInfosTabPage
+      // 
+      this.variableInfosTabPage.Controls.Add(this.operatorBaseVariableInfosView);
+      this.variableInfosTabPage.Location = new System.Drawing.Point(4, 22);
+      this.variableInfosTabPage.Name = "variableInfosTabPage";
+      this.variableInfosTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.variableInfosTabPage.Size = new System.Drawing.Size(499, 425);
+      this.variableInfosTabPage.TabIndex = 1;
+      this.variableInfosTabPage.Text = "Variable Infos";
+      this.variableInfosTabPage.UseVisualStyleBackColor = true;
+      // 
+      // operatorBaseVariableInfosView
+      // 
+      this.operatorBaseVariableInfosView.Caption = "Operator";
+      this.operatorBaseVariableInfosView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.operatorBaseVariableInfosView.Location = new System.Drawing.Point(3, 3);
+      this.operatorBaseVariableInfosView.Name = "operatorBaseVariableInfosView";
+      this.operatorBaseVariableInfosView.Operator = null;
+      this.operatorBaseVariableInfosView.Size = new System.Drawing.Size(493, 419);
+      this.operatorBaseVariableInfosView.TabIndex = 0;
+      // 
+      // tabPage1
+      // 
+      this.tabPage1.Controls.Add(this.variablesView);
+      this.tabPage1.Location = new System.Drawing.Point(4, 22);
+      this.tabPage1.Name = "tabPage1";
+      this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
+      this.tabPage1.Size = new System.Drawing.Size(499, 425);
+      this.tabPage1.TabIndex = 3;
+      this.tabPage1.Text = "Variables";
+      this.tabPage1.UseVisualStyleBackColor = true;
+      // 
+      // variablesView
+      // 
+      this.variablesView.Caption = "Operator";
+      this.variablesView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variablesView.Location = new System.Drawing.Point(3, 3);
+      this.variablesView.Name = "variablesView";
+      this.variablesView.Operator = null;
+      this.variablesView.Size = new System.Drawing.Size(493, 419);
+      this.variablesView.TabIndex = 0;
+      // 
+      // descriptionTabPage
+      // 
+      this.descriptionTabPage.Controls.Add(this.operatorBaseDescriptionView);
+      this.descriptionTabPage.Location = new System.Drawing.Point(4, 22);
+      this.descriptionTabPage.Name = "descriptionTabPage";
+      this.descriptionTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.descriptionTabPage.Size = new System.Drawing.Size(499, 425);
+      this.descriptionTabPage.TabIndex = 2;
+      this.descriptionTabPage.Text = "Description";
+      this.descriptionTabPage.UseVisualStyleBackColor = true;
+      // 
+      // operatorBaseDescriptionView
+      // 
+      this.operatorBaseDescriptionView.Caption = "Operator";
+      this.operatorBaseDescriptionView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.operatorBaseDescriptionView.Location = new System.Drawing.Point(3, 3);
+      this.operatorBaseDescriptionView.Name = "operatorBaseDescriptionView";
+      this.operatorBaseDescriptionView.Operator = null;
+      this.operatorBaseDescriptionView.Size = new System.Drawing.Size(493, 419);
+      this.operatorBaseDescriptionView.TabIndex = 0;
+      // 
+      // StructIdProblemInjectorView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "StructIdProblemInjectorView";
+      this.Size = new System.Drawing.Size(507, 451);
+      this.tabControl.ResumeLayout(false);
+      this.dataTabPage.ResumeLayout(false);
+      this.variableInfosTabPage.ResumeLayout(false);
+      this.tabPage1.ResumeLayout(false);
+      this.descriptionTabPage.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Button importInstanceButton;
+    private System.Windows.Forms.OpenFileDialog openFileDialog;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage dataTabPage;
+    private System.Windows.Forms.TabPage variableInfosTabPage;
+    private HeuristicLab.Core.OperatorBaseVariableInfosView operatorBaseVariableInfosView;
+    private System.Windows.Forms.TabPage descriptionTabPage;
+    private HeuristicLab.Core.OperatorBaseDescriptionView operatorBaseDescriptionView;
+    private System.Windows.Forms.TabPage tabPage1;
+    private HeuristicLab.Core.OperatorBaseVariablesView variablesView;
+    private HeuristicLab.DataAnalysis.DatasetView datasetView;
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.cs	(revision 656)
@@ -0,0 +1,154 @@
+#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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public partial class StructIdProblemInjectorView : ViewBase {
+    public StructIdProblemInjector StructIdProblemInjector {
+      get { return (StructIdProblemInjector)Item; }
+      set { base.Item = value; }
+    }
+
+    public StructIdProblemInjectorView()
+      : base() {
+      InitializeComponent();
+    }
+    public StructIdProblemInjectorView(StructIdProblemInjector structIdProblemInjector)
+      : this() {
+      StructIdProblemInjector = structIdProblemInjector;
+      variablesView.Operator = structIdProblemInjector;
+      variablesView.Update();
+    }
+
+    protected override void RemoveItemEvents() {
+      operatorBaseVariableInfosView.Operator = null;
+      operatorBaseDescriptionView.Operator = null;
+      base.RemoveItemEvents();
+    }
+    protected override void AddItemEvents() {
+      base.AddItemEvents();
+      operatorBaseVariableInfosView.Operator = StructIdProblemInjector;
+      operatorBaseDescriptionView.Operator = StructIdProblemInjector;
+    }
+
+    protected override void UpdateControls() {
+      base.UpdateControls();
+      if(StructIdProblemInjector == null) {
+        importInstanceButton.Enabled = false;
+      } else {
+        Dataset dataset = (Dataset)StructIdProblemInjector.GetVariable("Dataset").Value;
+        datasetView.Dataset = dataset;
+        importInstanceButton.Enabled = true;
+      }
+    }
+
+    private void importInstanceButton_Click(object sender, EventArgs e) {
+      if(openFileDialog.ShowDialog(this) == DialogResult.OK) {
+        DatasetParser parser = new DatasetParser();
+        bool success = false;
+        try {
+          try {
+            parser.Import(openFileDialog.FileName, true);
+            success = true;
+          } catch(DataFormatException ex) {
+            ShowWarningMessageBox(ex);
+            // not possible to parse strictly => clear and try to parse non-strict
+            parser.Reset();
+            parser.Import(openFileDialog.FileName, false);
+            success = true;
+          }
+        } catch(DataFormatException ex) {
+          // if the non-strict parsing also failed then show the exception
+          ShowErrorMessageBox(ex);
+        }
+        if(success) {
+          Dataset dataset = (Dataset)StructIdProblemInjector.GetVariable("Dataset").Value;
+          dataset.Rows = parser.Rows;
+          dataset.Columns = parser.Columns;
+          dataset.VariableNames = parser.VariableNames;
+          dataset.Name = parser.ProblemName;
+          dataset.Samples = new double[dataset.Rows * dataset.Columns];
+          Array.Copy(parser.Samples, dataset.Samples, dataset.Columns * dataset.Rows);
+          TrySetVariable("TrainingSamplesStart", parser.TrainingSamplesStart);
+          TrySetVariable("TrainingSamplesStart", parser.TrainingSamplesStart);
+          TrySetVariable("TrainingSamplesEnd", parser.TrainingSamplesEnd);
+          TrySetVariable("ValidationSamplesStart", parser.ValidationSamplesStart);
+          TrySetVariable("ValidationSamplesEnd", parser.ValidationSamplesEnd);
+          TrySetVariable("TestSamplesStart", parser.TestSamplesStart);
+          TrySetVariable("TestSamplesEnd", parser.TestSamplesEnd);
+          TrySetVariable("TargetVariable", parser.TargetVariable);
+
+          IVariable var = StructIdProblemInjector.GetVariable("AllowedFeatures");
+          if(var != null) {
+            ItemList<IntData> allowedFeatures = (ItemList<IntData>)var.Value;
+            allowedFeatures.Clear();
+            List<int> nonInputVariables = parser.NonInputVariables;
+            for(int i = 0; i < dataset.Columns; i++) {
+              if(!nonInputVariables.Contains(i)) allowedFeatures.Add(new IntData(i));
+            }
+          }
+          Refresh();
+        }
+      }
+    }
+
+    private void TrySetVariable(string name, int value) {
+      IVariable var = StructIdProblemInjector.GetVariable(name);
+      if(var != null) {
+        ((IntData)var.Value).Data = value;
+      }
+    }
+
+    private void ShowWarningMessageBox(Exception ex) {
+      MessageBox.Show(ex.Message,
+                      "Warning - " + ex.GetType().Name,
+                      MessageBoxButtons.OK,
+                      MessageBoxIcon.Warning);
+    }
+    private void ShowErrorMessageBox(Exception ex) {
+      MessageBox.Show(BuildErrorMessage(ex),
+                      "Error - " + ex.GetType().Name,
+                      MessageBoxButtons.OK,
+                      MessageBoxIcon.Error);
+    }
+    private string BuildErrorMessage(Exception ex) {
+      StringBuilder sb = new StringBuilder();
+      sb.Append("Sorry, but something went wrong!\n\n" + ex.Message + "\n\n" + ex.StackTrace);
+
+      while(ex.InnerException != null) {
+        ex = ex.InnerException;
+        sb.Append("\n\n-----\n\n" + ex.Message + "\n\n" + ex.StackTrace);
+      }
+      return sb.ToString();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.resx
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.resx	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/StructIdProblemInjectorView.resx	(revision 656)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="openFileDialog.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Subtraction.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Subtraction.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Subtraction.cs	(revision 656)
@@ -0,0 +1,51 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using System.Linq;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Subtraction : FunctionBase {
+    public override string Description {
+      get {
+        return @"Subtracts the results of sub-tree 2..n from the result of the first sub-tree.
+    (- 3) => -3
+    (- 2 3) => -1
+    (- 3 4 5) => -6";
+      }
+    }
+
+    public Subtraction()
+      : base() {
+      // 2 - 3 seems like an reasonable defaut (used for +,-,*,/) (discussion with swinkler and maffenze)
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 3));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+      AddConstraint(new SubOperatorTypeConstraint(2));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolTable.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolTable.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolTable.cs	(revision 656)
@@ -0,0 +1,93 @@
+﻿#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.Core;
+using System.Xml;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  class EvaluatorSymbolTable : StorableBase {
+    public const int ADDITION = 1;
+    public const int AND = 2;
+    public const int AVERAGE = 3;
+    public const int CONSTANT = 4;
+    public const int COSINUS = 5;
+    public const int DIFFERENTIAL = 25;
+    public const int DIVISION = 6;
+    public const int EQU = 7;
+    public const int EXP = 8;
+    public const int GT = 9;
+    public const int IFTE = 10;
+    public const int LT = 11;
+    public const int LOG = 12;
+    public const int MULTIPLICATION = 13;
+    public const int NOT = 14;
+    public const int OR = 15;
+    public const int POWER = 16;
+    public const int SIGNUM = 17;
+    public const int SINUS = 18;
+    public const int SQRT = 19;
+    public const int SUBTRACTION = 20;
+    public const int TANGENS = 21;
+    public const int VARIABLE = 22;
+    public const int XOR = 23;
+    public const int UNKNOWN = 24;
+
+    private static Dictionary<Type, int> staticTypes = new Dictionary<Type, int>();
+
+    // needs to be public for persistence mechanism (Activator.CreateInstance needs empty constructor)
+    static EvaluatorSymbolTable() {
+      staticTypes = new Dictionary<Type, int>();
+      staticTypes[typeof(Addition)] = ADDITION;
+      staticTypes[typeof(And)] = AND;
+      staticTypes[typeof(Average)] = AVERAGE;
+      staticTypes[typeof(Constant)] = CONSTANT;
+      staticTypes[typeof(Cosinus)] = COSINUS;
+      staticTypes[typeof(Division)] = DIVISION;
+      staticTypes[typeof(Equal)] = EQU;
+      staticTypes[typeof(Exponential)] = EXP;
+      staticTypes[typeof(GreaterThan)] = GT;
+      staticTypes[typeof(IfThenElse)] = IFTE;
+      staticTypes[typeof(LessThan)] = LT;
+      staticTypes[typeof(Logarithm)] = LOG;
+      staticTypes[typeof(Multiplication)] = MULTIPLICATION;
+      staticTypes[typeof(Not)] = NOT;
+      staticTypes[typeof(Or)] = OR;
+      staticTypes[typeof(Power)] = POWER;
+      staticTypes[typeof(Signum)] = SIGNUM;
+      staticTypes[typeof(Sinus)] = SINUS;
+      staticTypes[typeof(Sqrt)] = SQRT;
+      staticTypes[typeof(Subtraction)] = SUBTRACTION;
+      staticTypes[typeof(Tangens)] = TANGENS;
+      staticTypes[typeof(Variable)] = VARIABLE;
+      staticTypes[typeof(Xor)] = XOR;
+      staticTypes[typeof(Differential)] = DIFFERENTIAL;
+    }
+
+    internal static int MapFunction(IFunction function) {
+      if(staticTypes.ContainsKey(function.GetType())) return staticTypes[function.GetType()];
+      else return UNKNOWN;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolicExpressionExporter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolicExpressionExporter.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/SymbolicExpressionExporter.cs	(revision 656)
@@ -0,0 +1,219 @@
+﻿#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.Data;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class SymbolicExpressionExporter : IFunctionTreeExporter, IFunctionTreeNameGenerator {
+    private StringBuilder builder;
+    private string currentIndent;
+
+    #region IFunctionTreeExporter Members
+
+    public string Name {
+      get { return "Symbolic Expression Exporter"; }
+    }
+
+
+    public string Export(IFunctionTree tree) {
+      builder = new StringBuilder();
+      currentIndent = "";
+      BuildExportString(tree);
+      return builder.ToString();
+    }
+
+    public bool TryExport(IFunctionTree tree, out string exported) {
+      try {
+        exported = Export(tree);
+        return true;
+      } catch(UnknownFunctionException) {
+        exported = "";
+        return false;
+      }
+    }
+
+    private void BuildExportString(IFunctionTree tree) {
+      builder.Append(currentIndent);
+      builder.Append("(" + ExportFunction(tree.Function, tree) + " ");
+      currentIndent += "  ";
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        builder.Append("\n");
+        BuildExportString(subTree);
+      }
+      if(tree.SubTrees.Count > 0) builder.Append(")");
+      currentIndent = currentIndent.Remove(0, 2);
+    }
+
+    private string ExportFunction(IFunction function, IFunctionTree tree) {
+      // this is smelly, if there is a cleaner way to have a 'dynamic' visitor 
+      // please let me know! (gkronber 14.10.2008)
+      if(function is Addition) return ((Addition)function).ExportToScheme();
+      if(function is And) return ((And)function).ExportToScheme();
+      if(function is Average) return ((Average)function).ExportToScheme();
+      if(function is Constant) return ((Constant)function).ExportToScheme(tree);
+      if(function is Cosinus) return ((Cosinus)function).ExportToScheme();
+      if(function is Differential) return ((Differential)function).ExportToScheme(tree);
+      if(function is Division) return ((Division)function).ExportToScheme();
+      if(function is Equal) return ((Equal)function).ExportToScheme();
+      if(function is Exponential) return ((Exponential)function).ExportToScheme();
+      if(function is GreaterThan) return ((GreaterThan)function).ExportToScheme();
+      if(function is IfThenElse) return ((IfThenElse)function).ExportToScheme();
+      if(function is LessThan) return ((LessThan)function).ExportToScheme();
+      if(function is Logarithm) return ((Logarithm)function).ExportToScheme();
+      if(function is Multiplication) return ((Multiplication)function).ExportToScheme();
+      if(function is Not) return ((Not)function).ExportToScheme();
+      if(function is Or) return ((Or)function).ExportToScheme();
+      if(function is Power) return ((Power)function).ExportToScheme();
+      if(function is Signum) return ((Signum)function).ExportToScheme();
+      if(function is Sinus) return ((Sinus)function).ExportToScheme();
+      if(function is Sqrt) return ((Sqrt)function).ExportToScheme();
+      if(function is Subtraction) return ((Subtraction)function).ExportToScheme();
+      if(function is Tangens) return ((Tangens)function).ExportToScheme();
+      if(function is Variable) return ((Variable)function).ExportToScheme(tree);
+      if(function is Xor) return ((Xor)function).ExportToScheme();
+      throw new UnknownFunctionException(function.Name);
+    }
+
+
+    #endregion
+
+    #region IFunctionTreeNameGenerator Members
+
+    string IFunctionTreeNameGenerator.Name {
+      get { return "Symbolic Expression"; }
+    }
+
+    public string GetName(IFunctionTree tree) {
+      string name = "";
+      try {
+        name = ExportFunction(tree.Function, tree);
+      } catch(UnknownFunctionException) {
+        name = "N/A";
+      }
+      return name;
+    }
+
+    #endregion
+  }
+
+  internal static class SchemeExporterExtensions {
+    public static string ExportToScheme(this Addition addition) {
+      return "+";
+    }
+
+    public static string ExportToScheme(this Constant constant, IFunctionTree tree) {
+      return tree.GetLocalVariable(Constant.VALUE).Value.ToString();
+    }
+
+    public static string ExportToScheme(this Cosinus cosinus) {
+      return "cos";
+    }
+
+    public static string ExportToScheme(this Division division) {
+      return "/";
+    }
+
+    public static string ExportToScheme(this Exponential exponential) {
+      return "exp";
+    }
+
+    public static string ExportToScheme(this Logarithm logarithm) {
+      return "log";
+    }
+
+    public static string ExportToScheme(this Multiplication multiplication) {
+      return "*";
+    }
+
+    public static string ExportToScheme(this Power power) {
+      return "expt";
+    }
+
+    public static string ExportToScheme(this Signum signum) {
+      return "sign";
+    }
+
+    public static string ExportToScheme(this Sinus sinus) {
+      return "sin";
+    }
+
+    public static string ExportToScheme(this Sqrt sqrt) {
+      return "sqrt";
+    }
+
+    public static string ExportToScheme(this Subtraction subtraction) {
+      return "-";
+    }
+
+    public static string ExportToScheme(this Tangens tangens) {
+      return "tan";
+    }
+
+    public static string ExportToScheme(this Variable variable, IFunctionTree tree) {
+      return "(variable " + tree.GetLocalVariable(Variable.WEIGHT).Value + " " +
+        tree.GetLocalVariable(Variable.INDEX).Value + " " + tree.GetLocalVariable(Variable.OFFSET).Value + ")";
+    }
+    public static string ExportToScheme(this Differential differential, IFunctionTree tree) {
+      return "(differential " + tree.GetLocalVariable(Differential.WEIGHT).Value + " " +
+        tree.GetLocalVariable(Differential.INDEX).Value + " " + tree.GetLocalVariable(Differential.OFFSET).Value + ")";
+    }
+
+    public static string ExportToScheme(this And and) {
+      return "and";
+    }
+
+    public static string ExportToScheme(this Average average) {
+      return "mean";
+    }
+
+    public static string ExportToScheme(this IfThenElse ifThenElse) {
+      return "if";
+    }
+
+    public static string ExportToScheme(this Not not) {
+      return "not";
+    }
+
+    public static string ExportToScheme(this Or or) {
+      return "or";
+    }
+
+    public static string ExportToScheme(this Xor xor) {
+      return "xor";
+    }
+
+    public static string ExportToScheme(this Equal equal) {
+      return "equ";
+    }
+
+    public static string ExportToScheme(this LessThan lessThan) {
+      return "<";
+    }
+
+    public static string ExportToScheme(this GreaterThan greaterThan) {
+      return ">";
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Tangens.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Tangens.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Tangens.cs	(revision 656)
@@ -0,0 +1,43 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Tangens : FunctionBase {
+    public override string Description {
+      get { return "Returns the tangens of the first sub-tree."; }
+    }
+
+    public Tangens()
+      : base() {
+      // must have exactly one suboperator
+      AddConstraint(new NumberOfSubOperatorsConstraint(1, 1));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Variable.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Variable.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Variable.cs	(revision 656)
@@ -0,0 +1,210 @@
+#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.Text;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Random;
+using HeuristicLab.Operators;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public class Variable : FunctionBase {
+
+    public const string WEIGHT = "Weight";
+    public const string OFFSET = "SampleOffset";
+    public const string INDEX = "Variable";
+
+    private int minIndex;
+    private int maxIndex;
+    private int minOffset;
+    private int maxOffset;
+
+    public override string Description {
+      get {
+        return @"Variable reads a value from a dataset, multiplies that value with a given factor and returns the result.
+The variable 'SampleOffset' can be used to read a value from previous or following rows.
+The index of the row that is actually read is SampleIndex+SampleOffset).";
+      }
+    }
+
+    public Variable()
+      : base() {
+      AddVariableInfo(new VariableInfo(INDEX, "Index of the variable in the dataset representing this feature", typeof(ConstrainedIntData), VariableKind.None));
+      GetVariableInfo(INDEX).Local = true;
+      AddVariableInfo(new VariableInfo(WEIGHT, "Weight is multiplied to the feature value", typeof(ConstrainedDoubleData), VariableKind.None));
+      GetVariableInfo(WEIGHT).Local = true;
+      AddVariableInfo(new VariableInfo(OFFSET, "SampleOffset is added to the sample index", typeof(ConstrainedIntData), VariableKind.None));
+      GetVariableInfo(OFFSET).Local = true;
+      AddVariableInfo(new VariableInfo(INITIALIZATION, "Initialization operator for variables", typeof(CombinedOperator), VariableKind.None));
+      GetVariableInfo(INITIALIZATION).Local = false;
+      AddVariableInfo(new VariableInfo(MANIPULATION, "Manipulation operator for variables", typeof(CombinedOperator), VariableKind.None));
+      GetVariableInfo(MANIPULATION).Local = false;
+
+      ConstrainedDoubleData weight = new ConstrainedDoubleData();
+      // initialize a totally arbitrary range for the weight = [-20.0, 20.0]
+      weight.AddConstraint(new DoubleBoundedConstraint(-20.0, 20.0));
+      AddVariable(new HeuristicLab.Core.Variable(WEIGHT, weight));
+
+      ConstrainedIntData variable = new ConstrainedIntData();
+      AddVariable(new HeuristicLab.Core.Variable(INDEX, variable));
+      minIndex = 0; maxIndex = 100;
+
+      ConstrainedIntData sampleOffset = new ConstrainedIntData();
+      AddVariable(new HeuristicLab.Core.Variable(OFFSET, sampleOffset));
+
+      SetupInitialization();
+      SetupManipulation();
+
+      // variable can't have suboperators
+      AddConstraint(new NumberOfSubOperatorsConstraint(0, 0));
+    }
+
+    private void SetupInitialization() {
+      CombinedOperator combinedOp = new CombinedOperator();
+      SequentialProcessor seq = new SequentialProcessor();
+      UniformRandomizer indexRandomizer = new UniformRandomizer();
+      indexRandomizer.Min = minIndex;
+      indexRandomizer.Max = maxIndex + 1; // uniform randomizer generates numbers in the range [min, max[
+      indexRandomizer.GetVariableInfo("Value").ActualName = INDEX;
+      indexRandomizer.Name = "Index Randomizer";
+      NormalRandomizer weightRandomizer = new NormalRandomizer();
+      weightRandomizer.Mu = 1.0;
+      weightRandomizer.Sigma = 1.0;
+      weightRandomizer.GetVariableInfo("Value").ActualName = WEIGHT;
+      weightRandomizer.Name = "Weight Randomizer";
+      UniformRandomizer offsetRandomizer = new UniformRandomizer();
+      offsetRandomizer.Min = minOffset;
+      offsetRandomizer.Max = maxOffset + 1;
+      offsetRandomizer.GetVariableInfo("Value").ActualName = OFFSET;
+      offsetRandomizer.Name = "Offset Randomizer";
+
+      combinedOp.OperatorGraph.AddOperator(seq);
+      combinedOp.OperatorGraph.AddOperator(indexRandomizer);
+      combinedOp.OperatorGraph.AddOperator(weightRandomizer);
+      combinedOp.OperatorGraph.AddOperator(offsetRandomizer);
+      combinedOp.OperatorGraph.InitialOperator = seq;
+      seq.AddSubOperator(indexRandomizer);
+      seq.AddSubOperator(weightRandomizer);
+      seq.AddSubOperator(offsetRandomizer);
+      HeuristicLab.Core.IVariable initOp = GetVariable(INITIALIZATION);
+      if(initOp == null) {
+        AddVariable(new HeuristicLab.Core.Variable(INITIALIZATION, combinedOp));
+      } else {
+        initOp.Value = combinedOp;
+      }
+    }
+
+    private void SetupManipulation() {
+      // manipulation operator
+      CombinedOperator combinedOp = new CombinedOperator();
+      SequentialProcessor seq = new SequentialProcessor();
+      UniformRandomizer indexRandomizer = new UniformRandomizer();
+      indexRandomizer.Min = minIndex;
+      indexRandomizer.Max = maxIndex + 1;
+      indexRandomizer.GetVariableInfo("Value").ActualName = INDEX;
+      indexRandomizer.Name = "Index Randomizer";
+      NormalRandomAdder weightRandomAdder = new NormalRandomAdder();
+      weightRandomAdder.Mu = 0.0;
+      weightRandomAdder.Sigma = 0.1;
+      weightRandomAdder.GetVariableInfo("Value").ActualName = WEIGHT;
+      weightRandomAdder.Name = "Weight Adder";
+      NormalRandomAdder offsetRandomAdder = new NormalRandomAdder();
+      offsetRandomAdder.Mu = 0.0;
+      offsetRandomAdder.Sigma = 1.0;
+      offsetRandomAdder.GetVariableInfo("Value").ActualName = OFFSET;
+      offsetRandomAdder.Name = "Offset Adder";
+
+      combinedOp.OperatorGraph.AddOperator(seq);
+      combinedOp.OperatorGraph.AddOperator(indexRandomizer);
+      combinedOp.OperatorGraph.AddOperator(weightRandomAdder);
+      combinedOp.OperatorGraph.AddOperator(offsetRandomAdder);
+      combinedOp.OperatorGraph.InitialOperator = seq;
+      seq.AddSubOperator(indexRandomizer);
+      seq.AddSubOperator(weightRandomAdder);
+      seq.AddSubOperator(offsetRandomAdder);
+      HeuristicLab.Core.IVariable manipulationOp = GetVariable(MANIPULATION);
+      if(manipulationOp == null) {
+        AddVariable(new HeuristicLab.Core.Variable(MANIPULATION, combinedOp));
+      } else {
+        manipulationOp.Value = combinedOp;
+      }
+    }
+
+    public void SetConstraints(int[] allowedIndexes, int minSampleOffset, int maxSampleOffset) {
+      ConstrainedIntData offset = GetVariableValue<ConstrainedIntData>(OFFSET, null, false);
+      IntBoundedConstraint rangeConstraint = new IntBoundedConstraint();
+      this.minOffset = minSampleOffset;
+      this.maxOffset = maxSampleOffset;
+      rangeConstraint.LowerBound = minSampleOffset;
+      rangeConstraint.LowerBoundEnabled = true;
+      rangeConstraint.LowerBoundIncluded = true;
+      rangeConstraint.UpperBound = maxSampleOffset;
+      rangeConstraint.UpperBoundEnabled = true;
+      rangeConstraint.UpperBoundIncluded = true;
+      offset.AddConstraint(rangeConstraint);
+
+      ConstrainedIntData index = GetVariableValue<ConstrainedIntData>(INDEX, null, false);
+      Array.Sort(allowedIndexes);
+      minIndex = allowedIndexes[0]; maxIndex = allowedIndexes[allowedIndexes.Length - 1];
+      List<IConstraint> constraints = new List<IConstraint>();
+      int start = allowedIndexes[0];
+      int prev = start;
+      for(int i = 1; i < allowedIndexes.Length; i++) {
+        if(allowedIndexes[i] != prev + 1) {
+          IntBoundedConstraint lastRange = new IntBoundedConstraint();
+          lastRange.LowerBound = start;
+          lastRange.LowerBoundEnabled = true;
+          lastRange.LowerBoundIncluded = true;
+          lastRange.UpperBound = prev;
+          lastRange.UpperBoundEnabled = true;
+          lastRange.UpperBoundIncluded = true;
+          constraints.Add(lastRange);
+          start = allowedIndexes[i];
+          prev = start;
+        }
+        prev = allowedIndexes[i];
+      }
+      IntBoundedConstraint range = new IntBoundedConstraint();
+      range.LowerBound = start;
+      range.LowerBoundEnabled = true;
+      range.LowerBoundIncluded = true;
+      range.UpperBound = prev;
+      range.UpperBoundEnabled = true;
+      range.UpperBoundIncluded = true;
+      constraints.Add(range);
+      if(constraints.Count > 1) {
+        OrConstraint or = new OrConstraint();
+        foreach(IConstraint c in constraints) or.Clauses.Add(c);
+        index.AddConstraint(or);
+      } else {
+        index.AddConstraint(constraints[0]);
+      }
+
+      SetupInitialization();
+      SetupManipulation();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP.StructureIdentification/Xor.cs
===================================================================
--- trunk/sources/HeuristicLab.GP.StructureIdentification/Xor.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP.StructureIdentification/Xor.cs	(revision 656)
@@ -0,0 +1,44 @@
+#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.Constraints;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public sealed class Xor : FunctionBase {
+    public override string Description {
+      get {
+        return @"Logical XOR operation. Only defined for sub-tree-results 0.0 and 1.0.";
+      }
+    }
+
+    public Xor()
+      : base() {
+      AddConstraint(new NumberOfSubOperatorsConstraint(2, 2));
+      AddConstraint(new SubOperatorTypeConstraint(0));
+      AddConstraint(new SubOperatorTypeConstraint(1));
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/BakedFunctionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/BakedFunctionTree.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/BakedFunctionTree.cs	(revision 656)
@@ -0,0 +1,347 @@
+﻿#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.Core;
+using HeuristicLab.Data;
+using System.Xml;
+using System.Globalization;
+
+namespace HeuristicLab.GP {
+
+  public class LightWeightFunction {
+    public int arity = 0;
+    public IFunction functionType;
+    public List<double> data = new List<double>();
+
+    public LightWeightFunction Clone() {
+      LightWeightFunction clone = new LightWeightFunction();
+      clone.arity = arity;
+      clone.functionType = functionType;
+      clone.data.AddRange(data);
+      return clone;
+    }
+  }
+
+  public class BakedFunctionTree : ItemBase, IFunctionTree {
+    private List<LightWeightFunction> linearRepresentation;
+    public List<LightWeightFunction> LinearRepresentation {
+      get {
+        FlattenVariables();
+        FlattenTrees(); 
+        return linearRepresentation;
+      }
+    }
+    private bool treesExpanded = false;
+    private List<IFunctionTree> subTrees;
+    private bool variablesExpanded = false;
+    private List<IVariable> variables;
+
+    public BakedFunctionTree() {
+      linearRepresentation = new List<LightWeightFunction>();
+    }
+
+    internal BakedFunctionTree(IFunction function)
+      : this() {
+      LightWeightFunction fun = new LightWeightFunction();
+      fun.functionType = function;
+      linearRepresentation.Add(fun);
+      treesExpanded = true;
+      subTrees = new List<IFunctionTree>();
+      variables = new List<IVariable>();
+      variablesExpanded = true;
+      foreach(IVariableInfo variableInfo in function.VariableInfos) {
+        if(variableInfo.Local) {
+          variables.Add((IVariable)function.GetVariable(variableInfo.FormalName).Clone());
+        }
+      }
+    }
+
+    internal BakedFunctionTree(IFunctionTree tree)
+      : this() {
+      LightWeightFunction fun = new LightWeightFunction();
+      fun.functionType = tree.Function;
+      linearRepresentation.Add(fun);
+      foreach(IVariable variable in tree.LocalVariables) {
+        IItem value = variable.Value;
+        fun.data.Add(GetDoubleValue(value));
+      }
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        AddSubTree(new BakedFunctionTree(subTree));
+      }
+    }
+
+    private double GetDoubleValue(IItem value) {
+      if(value is DoubleData) {
+        return ((DoubleData)value).Data;
+      } else if(value is ConstrainedDoubleData) {
+        return ((ConstrainedDoubleData)value).Data;
+      } else if(value is IntData) {
+        return ((IntData)value).Data;
+      } else if(value is ConstrainedIntData) {
+        return ((ConstrainedIntData)value).Data;
+      } else throw new NotSupportedException("Invalid datatype of local variable for GP");
+    }
+
+    private int BranchLength(int branchRoot) {
+      int arity = linearRepresentation[branchRoot].arity;
+      int length = 1;
+      for(int i = 0; i < arity; i++) {
+        length += BranchLength(branchRoot + length);
+      }
+      return length;
+    }
+
+    private void FlattenTrees() {
+      if(treesExpanded) {
+        linearRepresentation[0].arity = subTrees.Count;
+        foreach(BakedFunctionTree subTree in subTrees) {
+          subTree.FlattenVariables();
+          subTree.FlattenTrees();
+          linearRepresentation.AddRange(subTree.linearRepresentation);
+        }
+        treesExpanded = false;
+        subTrees = null;
+      }
+    }
+
+    private void FlattenVariables() {
+      if(variablesExpanded) {
+        linearRepresentation[0].data.Clear();
+        foreach(IVariable variable in variables) {
+          linearRepresentation[0].data.Add(GetDoubleValue(variable.Value));
+        }
+        variablesExpanded = false;
+        variables = null;
+      }
+    }
+
+    public int Size {
+      get {
+        if(treesExpanded) {
+          int size = 1;
+          foreach(BakedFunctionTree tree in subTrees) {
+            size += tree.Size;
+          }
+          return size;
+        } else 
+        return linearRepresentation.Count;
+      }
+    }
+
+    public int Height {
+      get {
+        if(treesExpanded) {
+          int height = 0;
+          foreach(IFunctionTree subTree in subTrees) {
+            int curHeight = subTree.Height;
+            if(curHeight > height) height = curHeight;
+          }
+          return height+1;
+        } else {
+          int nextBranchStart;
+          return BranchHeight(0, out nextBranchStart);
+        }
+      }
+    }
+
+    private int BranchHeight(int branchStart, out int nextBranchStart) {
+      LightWeightFunction f = linearRepresentation[branchStart];
+      int height = 0;
+      branchStart++;
+      for(int i = 0; i < f.arity; i++) {
+        int curHeight = BranchHeight(branchStart, out nextBranchStart);
+        if(curHeight > height) height = curHeight;
+        branchStart = nextBranchStart;
+      }
+      nextBranchStart = branchStart;
+      return height + 1;
+    }
+
+    public IList<IFunctionTree> SubTrees {
+      get {
+        if(!treesExpanded) {
+          subTrees = new List<IFunctionTree>();
+          int arity = linearRepresentation[0].arity;
+          int branchIndex = 1;
+          for(int i = 0; i < arity; i++) {
+            BakedFunctionTree subTree = new BakedFunctionTree();
+            int length = BranchLength(branchIndex);
+            for(int j = branchIndex; j < branchIndex + length; j++) {
+              subTree.linearRepresentation.Add(linearRepresentation[j]);
+            }
+            branchIndex += length;
+            subTrees.Add(subTree);
+          }
+          treesExpanded = true;
+          linearRepresentation.RemoveRange(1, linearRepresentation.Count - 1);
+          linearRepresentation[0].arity = 0;
+        }
+        return subTrees;
+      }
+    }
+
+    public ICollection<IVariable> LocalVariables {
+      get {
+        if(!variablesExpanded) {
+          variables = new List<IVariable>();
+          IFunction function = Function;
+          int localVariableIndex = 0;
+          foreach(IVariableInfo variableInfo in function.VariableInfos) {
+            if(variableInfo.Local) {
+              IVariable clone = (IVariable)function.GetVariable(variableInfo.FormalName).Clone();
+              IItem value = clone.Value;
+              if(value is ConstrainedDoubleData) {
+                ((ConstrainedDoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
+              } else if(value is ConstrainedIntData) {
+                ((ConstrainedIntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
+              } else if(value is DoubleData) {
+                ((DoubleData)value).Data = linearRepresentation[0].data[localVariableIndex];
+              } else if(value is IntData) {
+                ((IntData)value).Data = (int)linearRepresentation[0].data[localVariableIndex];
+              } else throw new NotSupportedException("Invalid local variable type for GP.");
+              variables.Add(clone);
+              localVariableIndex++;
+            }
+          }
+          variablesExpanded = true;
+          linearRepresentation[0].data.Clear();
+        }
+        return variables;
+      }
+    }
+
+    public IFunction Function {
+      get { return linearRepresentation[0].functionType; }
+    }
+
+    public IVariable GetLocalVariable(string name) {
+      foreach(IVariable var in LocalVariables) {
+        if(var.Name == name) return var;
+      }
+      return null;
+    }
+
+    public void AddVariable(IVariable variable) {
+      throw new NotSupportedException();
+    }
+
+    public void RemoveVariable(string name) {
+      throw new NotSupportedException();
+    }
+
+    public void AddSubTree(IFunctionTree tree) {
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.Add(tree);
+    }
+
+    public void InsertSubTree(int index, IFunctionTree tree) {
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.Insert(index, tree);
+    }
+
+    public void RemoveSubTree(int index) {
+      // sanity check
+      if(!treesExpanded) throw new InvalidOperationException();
+      subTrees.RemoveAt(index);
+    }
+
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      FlattenVariables();
+      FlattenTrees();
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      XmlNode linearRepresentationNode = document.CreateElement("LinearRepresentation");
+      foreach(LightWeightFunction f in linearRepresentation) {
+        XmlNode entryNode = PersistenceManager.Persist("FunctionType", f.functionType, document, persistedObjects);
+        XmlAttribute arityAttribute = document.CreateAttribute("Arity");
+        arityAttribute.Value = f.arity+"";
+        entryNode.Attributes.Append(arityAttribute);
+        if(f.data.Count > 0) {
+          XmlAttribute dataAttribute = document.CreateAttribute("Data");
+          dataAttribute.Value = GetString(f.data);
+          entryNode.Attributes.Append(dataAttribute);
+        }
+        linearRepresentationNode.AppendChild(entryNode);
+      }
+
+      node.AppendChild(linearRepresentationNode);
+      return node;
+    }
+
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      XmlNode linearRepresentationNode = node.SelectSingleNode("LinearRepresentation");
+      foreach(XmlNode entryNode in linearRepresentationNode.ChildNodes) {
+        LightWeightFunction f = new LightWeightFunction();
+        f.arity = int.Parse(entryNode.Attributes["Arity"].Value, CultureInfo.InvariantCulture);
+        if(entryNode.Attributes["Data"]!=null) 
+          f.data = GetList<double>(entryNode.Attributes["Data"].Value, s => double.Parse(s, CultureInfo.InvariantCulture));
+        f.functionType = (IFunction)PersistenceManager.Restore(entryNode, restoredObjects);
+        linearRepresentation.Add(f);
+      }
+      treesExpanded = false;
+      variablesExpanded = false;
+    }
+
+    private string GetString(IEnumerable<double> xs) {
+      StringBuilder builder = new StringBuilder();
+      foreach(double x in xs) {
+        builder.Append(x.ToString("r", CultureInfo.InvariantCulture) + "; ");
+      }
+      if(builder.Length > 0) builder.Remove(builder.Length - 2, 2);
+      return builder.ToString();
+    }
+
+    private List<T> GetList<T>(string s, Converter<string, T> converter) {
+      List<T> result = new List<T>();
+      string[] tokens = s.Split(new char[] { ';', ' ' }, StringSplitOptions.RemoveEmptyEntries);
+      foreach(string token in tokens) {
+        T x = converter(token.Trim());
+        result.Add(x);
+      }
+      return result;
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      BakedFunctionTree clone = new BakedFunctionTree();
+      // in case the user (de)serialized the tree between evaluation and selection we have to flatten the tree again.
+      if(treesExpanded) FlattenTrees();
+      if(variablesExpanded) FlattenVariables();
+      foreach(LightWeightFunction f in linearRepresentation) {
+        clone.linearRepresentation.Add(f.Clone());
+      }
+      return clone;
+    }
+
+    public override IView CreateView() {
+      return new FunctionTreeView(this);
+    }
+
+    //public override string ToString() {
+    //  SymbolicExpressionExporter exporter = new SymbolicExpressionExporter();
+    //  exporter.Visit(this);
+    //  return exporter.GetStringRepresentation();
+    //}
+  }
+}
Index: trunk/sources/HeuristicLab.GP/DefaultFunctionTreeNameGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/DefaultFunctionTreeNameGenerator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/DefaultFunctionTreeNameGenerator.cs	(revision 656)
@@ -0,0 +1,39 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public class DefaultFunctionTreeNameGenerator : IFunctionTreeNameGenerator {
+    #region IFunctionTreeNameGenerator Members
+    string IFunctionTreeNameGenerator.Name {
+      get { return "Default Representation"; }
+    }
+
+    string IFunctionTreeNameGenerator.GetName(IFunctionTree tree) {
+      return tree.Function.Name;
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.GP/FunctionBase.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/FunctionBase.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/FunctionBase.cs	(revision 656)
@@ -0,0 +1,157 @@
+#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.Text;
+using HeuristicLab.Data;
+using HeuristicLab.Core;
+using System.Xml;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  /// <summary>
+  /// Functions are like operators except that they do not allow sub-operators and the normal form of evaluation
+  /// is to evaluate all children first.
+  /// </summary>
+  public abstract class FunctionBase : OperatorBase, IFunction {
+    public const string INITIALIZATION = "Initialization";
+    public const string MANIPULATION = "Manipulation";
+    private List<IFunction>[] allowedSubFunctions;
+    private int minArity = -1;
+    private int maxArity = -1;
+
+    public virtual double Apply() {
+      throw new NotImplementedException();
+    }
+
+    public virtual IFunctionTree GetTreeNode() {
+      return new BakedFunctionTree(this);
+    }
+
+    public int MinArity {
+      get {
+        if(minArity < 0) RefreshArity();
+        return minArity;
+      }
+    }
+
+    public int MaxArity {
+      get {
+        if(maxArity < 0) RefreshArity();
+        return maxArity;
+      }
+    }
+
+    private void RefreshArity() {
+      minArity = 2; maxArity = 2; // default arity is 2
+      foreach(IConstraint constraint in Constraints) {
+        NumberOfSubOperatorsConstraint theConstraint = constraint as NumberOfSubOperatorsConstraint;
+        if(theConstraint != null) {
+          minArity = theConstraint.MinOperators.Data;
+          maxArity = theConstraint.MaxOperators.Data;
+        }
+      }
+    }
+
+    public IList<IFunction> AllowedSubFunctions(int index) {
+      if(allowedSubFunctions == null) {
+        // first time: analyze the constraint and create a cached copy of the allowed sub-functions
+        allowedSubFunctions = new List<IFunction>[MaxArity];
+        for(int i = 0; i < MaxArity; i++) {
+          allowedSubFunctions[i] = GetAllowedSubFunctions(i);
+        }
+      }
+      return allowedSubFunctions[index];
+    }
+
+    private List<IFunction> GetAllowedSubFunctions(int index) {
+      List<IFunction> allowedSubFunctions = new List<IFunction>();
+      foreach(IConstraint constraint in Constraints) {
+        if(constraint is SubOperatorTypeConstraint) {
+          SubOperatorTypeConstraint subOpConstraint = constraint as SubOperatorTypeConstraint;
+          if(subOpConstraint.SubOperatorIndex.Data == index) {
+            foreach(IFunction f in subOpConstraint.AllowedSubOperators) allowedSubFunctions.Add(f);
+            subOpConstraint.Changed += new EventHandler(subOpConstraint_Changed); // register an event-handler to invalidate the cache on constraing changes
+            return allowedSubFunctions;
+          }
+        } else if(constraint is AllSubOperatorsTypeConstraint) {
+          AllSubOperatorsTypeConstraint subOpConstraint = constraint as AllSubOperatorsTypeConstraint;
+          foreach(IFunction f in subOpConstraint.AllowedSubOperators) allowedSubFunctions.Add(f);
+          subOpConstraint.Changed += new EventHandler(subOpConstraint_Changed); // register an event-handler to invalidate the cache on constraint changes
+          return allowedSubFunctions;
+        }
+      }
+      return allowedSubFunctions;
+    }
+
+    private void subOpConstraint_Changed(object sender, EventArgs e) {
+      allowedSubFunctions = null;
+    }
+
+    // operator-tree style evaluation is not supported for functions.
+    public override IOperation Apply(IScope scope) {
+      throw new NotSupportedException();
+    }
+
+    private static readonly List<IOperator> emptySubOperatorList = new List<IOperator>();
+    public override IList<IOperator> SubOperators {
+      get { return emptySubOperatorList; }
+    }
+
+    public override void AddSubOperator(IOperator subOperator) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryAddSubOperator(IOperator subOperator) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryAddSubOperator(IOperator subOperator, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
+      throw new NotSupportedException();
+    }
+
+    public override void AddSubOperator(IOperator subOperator, int index) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveSubOperator(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryRemoveSubOperator(int index) {
+      throw new NotSupportedException();
+    }
+
+    public override bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
+      throw new NotSupportedException();
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/FunctionView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/FunctionView.Designer.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/FunctionView.Designer.cs	(revision 656)
@@ -0,0 +1,198 @@
+#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;
+namespace HeuristicLab.GP {
+  partial class FunctionTreeView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      if(selectedVariable != null) {
+        selectedVariable.Value.Changed -= new EventHandler(selectedVariable_ValueChanged);
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.funTreeView = new System.Windows.Forms.TreeView();
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.variablesGroupBox = new System.Windows.Forms.GroupBox();
+      this.variablesSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.variablesListBox = new System.Windows.Forms.ListBox();
+      this.label1 = new System.Windows.Forms.Label();
+      this.templateTextBox = new System.Windows.Forms.TextBox();
+      this.editButton = new System.Windows.Forms.Button();
+      this.treeNodeContextMenu = new System.Windows.Forms.ContextMenu();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.variablesGroupBox.SuspendLayout();
+      this.variablesSplitContainer.Panel1.SuspendLayout();
+      this.variablesSplitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // funTreeView
+      // 
+      this.funTreeView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.funTreeView.HideSelection = false;
+      this.funTreeView.Location = new System.Drawing.Point(0, 0);
+      this.funTreeView.Name = "funTreeView";
+      this.funTreeView.Size = new System.Drawing.Size(182, 532);
+      this.funTreeView.TabIndex = 0;
+      this.funTreeView.MouseUp += new System.Windows.Forms.MouseEventHandler(this.funTreeView_MouseUp);
+      this.funTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.functionTreeView_AfterSelect);
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.funTreeView);
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.variablesGroupBox);
+      this.splitContainer.Panel2.Controls.Add(this.label1);
+      this.splitContainer.Panel2.Controls.Add(this.templateTextBox);
+      this.splitContainer.Panel2.Controls.Add(this.editButton);
+      this.splitContainer.Size = new System.Drawing.Size(735, 532);
+      this.splitContainer.SplitterDistance = 182;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // variablesGroupBox
+      // 
+      this.variablesGroupBox.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.variablesGroupBox.Controls.Add(this.variablesSplitContainer);
+      this.variablesGroupBox.Location = new System.Drawing.Point(3, 31);
+      this.variablesGroupBox.Name = "variablesGroupBox";
+      this.variablesGroupBox.Size = new System.Drawing.Size(543, 498);
+      this.variablesGroupBox.TabIndex = 5;
+      this.variablesGroupBox.TabStop = false;
+      this.variablesGroupBox.Text = "Local variables";
+      // 
+      // variablesSplitContainer
+      // 
+      this.variablesSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variablesSplitContainer.Location = new System.Drawing.Point(3, 16);
+      this.variablesSplitContainer.Name = "variablesSplitContainer";
+      // 
+      // variablesSplitContainer.Panel1
+      // 
+      this.variablesSplitContainer.Panel1.Controls.Add(this.variablesListBox);
+      this.variablesSplitContainer.Size = new System.Drawing.Size(537, 479);
+      this.variablesSplitContainer.SplitterDistance = 179;
+      this.variablesSplitContainer.TabIndex = 0;
+      // 
+      // variablesListBox
+      // 
+      this.variablesListBox.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.variablesListBox.FormattingEnabled = true;
+      this.variablesListBox.Location = new System.Drawing.Point(0, 0);
+      this.variablesListBox.Name = "variablesListBox";
+      this.variablesListBox.Size = new System.Drawing.Size(179, 472);
+      this.variablesListBox.TabIndex = 0;
+      this.variablesListBox.SelectedIndexChanged += new System.EventHandler(this.variablesListBox_SelectedIndexChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 10);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(96, 13);
+      this.label1.TabIndex = 3;
+      this.label1.Text = "Function definition:";
+      // 
+      // templateTextBox
+      // 
+      this.templateTextBox.Location = new System.Drawing.Point(105, 7);
+      this.templateTextBox.Name = "templateTextBox";
+      this.templateTextBox.ReadOnly = true;
+      this.templateTextBox.Size = new System.Drawing.Size(190, 20);
+      this.templateTextBox.TabIndex = 2;
+      // 
+      // editButton
+      // 
+      this.editButton.Enabled = false;
+      this.editButton.Location = new System.Drawing.Point(301, 5);
+      this.editButton.Name = "editButton";
+      this.editButton.Size = new System.Drawing.Size(49, 23);
+      this.editButton.TabIndex = 1;
+      this.editButton.Text = "Edit...";
+      this.editButton.UseVisualStyleBackColor = true;
+      this.editButton.Click += new System.EventHandler(this.editButton_Click);
+      // 
+      // treeNodeContextMenu
+      // 
+      this.treeNodeContextMenu.Name = "treeNodeContextMenu";
+      // 
+      // FunctionTreeView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "FunctionTreeView";
+      this.Size = new System.Drawing.Size(735, 532);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      this.splitContainer.Panel2.PerformLayout();
+      this.splitContainer.ResumeLayout(false);
+      this.variablesGroupBox.ResumeLayout(false);
+      this.variablesSplitContainer.Panel1.ResumeLayout(false);
+      this.variablesSplitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TreeView funTreeView;
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.TextBox templateTextBox;
+    private System.Windows.Forms.Button editButton;
+    private System.Windows.Forms.GroupBox variablesGroupBox;
+    private System.Windows.Forms.SplitContainer variablesSplitContainer;
+    private System.Windows.Forms.ListBox variablesListBox;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ContextMenu treeNodeContextMenu;
+  }
+}
Index: trunk/sources/HeuristicLab.GP/FunctionView.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/FunctionView.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/FunctionView.cs	(revision 656)
@@ -0,0 +1,181 @@
+#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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.GP {
+  public partial class FunctionTreeView : ViewBase {
+    private IFunctionTree functionTree;
+
+    private IFunctionTree selectedBranch;
+    private IVariable selectedVariable;
+    private IFunctionTreeNameGenerator nameGenerator;
+    private IFunctionTreeNameGenerator[] allNameGenerators;
+    private MenuItem representationsMenu;
+
+    public FunctionTreeView() {
+      nameGenerator = new DefaultFunctionTreeNameGenerator();
+      InitializeComponent();
+
+      DiscoveryService discoveryService = new DiscoveryService();
+      allNameGenerators = discoveryService.GetInstances<IFunctionTreeNameGenerator>();
+      representationsMenu = new MenuItem();
+      representationsMenu.Text = "Tree representation";
+      representationsMenu.Name = "Tree representation";
+      foreach(IFunctionTreeNameGenerator generator in allNameGenerators) {
+        MenuItem mi = new MenuItem(generator.Name, 
+          delegate(object source, EventArgs args) {
+            IFunctionTreeNameGenerator g = (IFunctionTreeNameGenerator)((MenuItem)source).Tag;
+            this.nameGenerator = g;
+            foreach(MenuItem otherMenuItem in representationsMenu.MenuItems) otherMenuItem.Checked = false;
+            ((MenuItem)source).Checked = true;
+            UpdateControls();
+          }, Shortcut.None);
+        if(generator is DefaultFunctionTreeNameGenerator) mi.Checked = true;
+        else mi.Checked = false;
+        mi.Tag = generator;
+        representationsMenu.MenuItems.Add(mi);
+      }
+    }
+
+    public FunctionTreeView(IFunctionTree functionTree)
+      : this() {
+      this.functionTree = functionTree;
+      Refresh();
+    }
+
+    protected override void UpdateControls() {
+      funTreeView.Nodes.Clear();
+      TreeNode rootNode = new TreeNode();
+      rootNode.Name = functionTree.Function.Name;
+      rootNode.Text = nameGenerator.GetName(functionTree);
+      rootNode.Tag = functionTree;
+      treeNodeContextMenu.MenuItems.Clear();
+      treeNodeContextMenu.MenuItems.Add(representationsMenu);
+      DiscoveryService discoveryService = new DiscoveryService();
+      IFunctionTreeExporter[] exporters = discoveryService.GetInstances<IFunctionTreeExporter>();
+      foreach(IFunctionTreeExporter exporter in exporters) {
+        string result;
+        // register a menu item for the exporter
+        MenuItem item = new MenuItem("Copy to clip-board (" + exporter.Name + ")", 
+          delegate(object source, EventArgs args) {
+            TreeNode node = funTreeView.SelectedNode;
+            if(node == null || node.Tag == null) return;
+            Clipboard.SetText(exporter.Export((IFunctionTree)node.Tag));
+          }, Shortcut.None);
+        // try to export the whole tree 
+        if(exporter.TryExport(functionTree, out result)) {
+          // if it worked enable the context-menu item
+          item.Enabled = true;
+        } else {
+          item.Enabled = false;
+        }
+        treeNodeContextMenu.MenuItems.Add(item);
+      }
+      rootNode.ContextMenu = treeNodeContextMenu;
+      funTreeView.Nodes.Add(rootNode);
+
+      foreach(IFunctionTree subTree in functionTree.SubTrees) {
+        CreateTree(rootNode, subTree);
+      }
+      funTreeView.ExpandAll();
+    }
+
+    private void CreateTree(TreeNode rootNode, IFunctionTree functionTree) {
+      TreeNode node = new TreeNode();
+      node.Name = functionTree.Function.Name;
+      node.Text = nameGenerator.GetName(functionTree);
+      node.Tag = functionTree;
+      node.ContextMenu = treeNodeContextMenu;
+      rootNode.Nodes.Add(node);
+      foreach(IFunctionTree subTree in functionTree.SubTrees) {
+        CreateTree(node, subTree);
+      }
+    }
+
+    private void functionTreeView_AfterSelect(object sender, TreeViewEventArgs e) {
+      variablesListBox.Items.Clear();
+      variablesSplitContainer.Panel2.Controls.Clear();
+      templateTextBox.Clear();
+      editButton.Enabled = false;
+      if(funTreeView.SelectedNode != null && funTreeView.SelectedNode.Tag != null) {
+        IFunctionTree selectedBranch = (IFunctionTree)funTreeView.SelectedNode.Tag;
+        UpdateVariablesList(selectedBranch);
+        templateTextBox.Text = nameGenerator.GetName(selectedBranch);
+        this.selectedBranch = selectedBranch;
+        editButton.Enabled = true;
+      }
+    }
+
+    private void UpdateVariablesList(IFunctionTree functionTree) {
+      foreach(IVariable variable in functionTree.LocalVariables) {
+        variablesListBox.Items.Add(variable.Name);
+      }
+    }
+
+    private void variablesListBox_SelectedIndexChanged(object sender, EventArgs e) {
+      // in case we had an event-handler registered for a different variable => unregister the event-handler
+      if(selectedVariable != null) {
+        selectedVariable.Value.Changed -= new EventHandler(selectedVariable_ValueChanged);
+      }
+      if(variablesListBox.SelectedItem != null) {
+        string selectedVariableName = (string)variablesListBox.SelectedItem;
+        selectedVariable = selectedBranch.GetLocalVariable(selectedVariableName);
+        variablesSplitContainer.Panel2.Controls.Clear();
+        Control editor = (Control)selectedVariable.CreateView();
+        variablesSplitContainer.Panel2.Controls.Add(editor);
+        editor.Dock = DockStyle.Fill;
+        // register an event handler that updates the treenode when the value of the variable is changed by the user
+        selectedVariable.Value.Changed += new EventHandler(selectedVariable_ValueChanged);
+      } else {
+        variablesSplitContainer.Panel2.Controls.Clear();
+      }
+    }
+
+    void selectedVariable_ValueChanged(object sender, EventArgs e) {
+      if(funTreeView.SelectedNode != null && funTreeView.SelectedNode.Tag != null) {
+        TreeNode node = funTreeView.SelectedNode;
+        node.Text = nameGenerator.GetName(functionTree);
+      }
+    }
+
+    protected virtual void editButton_Click(object sender, EventArgs e) {
+      PluginManager.ControlManager.ShowControl(selectedBranch.Function.CreateView());
+    }
+
+    private void funTreeView_MouseUp(object sender, MouseEventArgs e) {
+      if(e.Button == MouseButtons.Right) {
+        // Select the clicked node
+        funTreeView.SelectedNode = funTreeView.GetNodeAt(e.X, e.Y);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/FunctionView.resx
===================================================================
--- trunk/sources/HeuristicLab.GP/FunctionView.resx	(revision 656)
+++ trunk/sources/HeuristicLab.GP/FunctionView.resx	(revision 656)
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="representationContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>180, 17</value>
+  </metadata>
+  <metadata name="treeNodeContextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: trunk/sources/HeuristicLab.GP/GPOperatorGroup.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/GPOperatorGroup.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/GPOperatorGroup.cs	(revision 656)
@@ -0,0 +1,228 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Data;
+using HeuristicLab.Random;
+using HeuristicLab.Constraints;
+
+namespace HeuristicLab.GP {
+  public class GPOperatorGroup : OperatorGroup {
+    private Dictionary<IOperator, int> minTreeHeight = new Dictionary<IOperator, int>();
+    private Dictionary<IOperator, int> minTreeSize = new Dictionary<IOperator, int>();
+    private SubOperatorsConstraintAnalyser constraintAnalyser = new SubOperatorsConstraintAnalyser();
+
+    public GPOperatorGroup()
+      : base() {
+    }
+
+    public override void AddOperator(IOperator op) {
+      base.AddOperator(op);
+      var localVariableInfos = op.VariableInfos.Where(f => f.Local);
+
+      if(op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT) == null) {
+        op.AddVariable(new Variable(GPOperatorLibrary.MIN_TREE_HEIGHT, new IntData(-1)));
+      }
+      if(op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE) == null) {
+        op.AddVariable(new Variable(GPOperatorLibrary.MIN_TREE_SIZE, new IntData(-1)));
+      }
+      if(op.GetVariable(GPOperatorLibrary.TICKETS) == null) {
+        op.AddVariable(new Variable(GPOperatorLibrary.TICKETS, new DoubleData(1.0)));
+      }
+      foreach(IConstraint c in op.Constraints) {
+        if(c is SubOperatorTypeConstraint || c is AllSubOperatorsTypeConstraint) c.Changed += new EventHandler(UpdateTreeBounds);
+      }
+      RecalculateMinimalTreeBounds();
+      OnOperatorAdded(op);
+    }
+
+    void UpdateTreeBounds(object sender, EventArgs e) {
+      RecalculateMinimalTreeBounds();
+    }
+
+    private void RecalculateMinimalTreeBounds() {
+      minTreeHeight.Clear();
+      minTreeSize.Clear();
+      constraintAnalyser.AllPossibleOperators = Operators;
+
+      foreach(IOperator op in Operators) {
+        ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data = RecalculateMinimalTreeHeight(op);
+        ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data = RecalculateMinimalTreeSize(op);
+      }
+    }
+
+    private int RecalculateMinimalTreeSize(IOperator op) {
+      // check for memoized value
+      if(minTreeSize.ContainsKey(op)) {
+        return minTreeSize[op];
+      }
+
+      int minArity;
+      int maxArity;
+      GetMinMaxArity(op, out minArity, out maxArity);
+      // no suboperators possible => minimalTreeSize == 1 (the current node)
+      if(minArity == 0 && maxArity == 0) {
+        minTreeSize[op] = 1;
+        return 1;
+      }
+
+      // when suboperators are necessary we have to find the smallest possible tree (recursively)
+      // the minimal size of the parent is 1 + the sum of the minimal sizes of all subtrees
+      int subTreeSizeSum = 0;
+
+      // mark the currently processed operator to prevent infinite recursions and stack overflow
+      minTreeSize[op] = 9999;
+      for(int i = 0; i < minArity; i++) {
+        // calculate the minTreeSize of all allowed sub-operators 
+        // if the list of allowed suboperators is empty because the operator needs suboperators 
+        // but there are no valid suboperators defined in the current group then we just use an impossible 
+        // tree size here to indicate that there was a problem.
+        // usually as more operators are added to the group the problem will be corrected (by adding the missing operator).
+        // however if the missing operator is never added the high min tree size here has the effect that this operator
+        // will not be included in generated subtrees because the resulting size would always be higher than a reasonably set 
+        // maximal tree size.
+        int minSubTreeSize = constraintAnalyser.GetAllowedOperators(op, i).Select(subOp => RecalculateMinimalTreeSize(subOp))
+          .Concat(Enumerable.Repeat(9999, 1)).Min();
+        subTreeSizeSum += minSubTreeSize;
+      }
+
+      minTreeSize[op] = subTreeSizeSum + 1;
+      return subTreeSizeSum + 1;
+    }
+
+    private int RecalculateMinimalTreeHeight(IOperator op) {
+      // check for memoized value
+      if(minTreeHeight.ContainsKey(op)) {
+        return minTreeHeight[op];
+      }
+
+      int minArity;
+      int maxArity;
+      GetMinMaxArity(op, out minArity, out maxArity);
+      // no suboperators possible => minimalTreeHeight == 1
+      if(minArity == 0 && maxArity == 0) {
+        minTreeHeight[op] = 1;
+        return 1;
+      }
+
+      // when suboperators are necessary we have to find the smallest possible tree (recursively)
+      // the minimal height of the parent is 1 + the height of the largest subtree
+      int maxSubTreeHeight = 0;
+
+      // mark the currently processed operator to prevent infinite recursions leading to stack overflow
+      minTreeHeight[op] = 9999;
+      for(int i = 0; i < minArity; i++) {
+        // calculate the minTreeHeight of all possible sub-operators.
+        // use the smallest possible subTree as lower bound for the subTreeHeight.
+        // if the list of allowed suboperators is empty because the operator needs suboperators 
+        // but there are no valid suboperators defined in the current group then we use an impossible tree height
+        // to indicate that there was a problem.
+        // usually as more operators are added to the group the problem will be corrected (by adding the missing operator).
+        // however if the missing operator is never added the high min tree height here has the effect that this operator
+        // will not be included in generated subtrees because the resulting (virtual) height would always be higher than a reasonably set 
+        // maximal tree height.
+        int minSubTreeHeight = constraintAnalyser.GetAllowedOperators(op, i).Select(subOp => RecalculateMinimalTreeHeight(subOp))
+          .Concat(Enumerable.Repeat(9999, 1)).Min();
+
+        // if the smallest height of this subtree is larger than all other subtrees before we have to update the min height of the parent
+        if(minSubTreeHeight > maxSubTreeHeight) {
+          maxSubTreeHeight = minSubTreeHeight;
+        }
+      }
+
+      minTreeHeight[op] = maxSubTreeHeight + 1;
+      return maxSubTreeHeight + 1;
+    }
+
+    private void GetMinMaxArity(IOperator op, out int minArity, out int maxArity) {
+      foreach(IConstraint constraint in op.Constraints) {
+        NumberOfSubOperatorsConstraint theConstraint = constraint as NumberOfSubOperatorsConstraint;
+        if(theConstraint != null) {
+          minArity = theConstraint.MinOperators.Data;
+          maxArity = theConstraint.MaxOperators.Data;
+          return;
+        }
+      }
+      // the default arity is 2
+      minArity = 2;
+      maxArity = 2;
+    }
+
+    public override void AddSubGroup(IOperatorGroup group) {
+      throw new NotSupportedException();
+    }
+
+    public override void RemoveOperator(IOperator op) {
+      base.RemoveOperator(op);
+      op.RemoveVariable(GPOperatorLibrary.MIN_TREE_SIZE);
+      op.RemoveVariable(GPOperatorLibrary.MIN_TREE_HEIGHT);
+      op.RemoveVariable(GPOperatorLibrary.TICKETS);
+      foreach(IConstraint c in op.Constraints) {
+        if(c is SubOperatorTypeConstraint || c is AllSubOperatorsTypeConstraint) c.Changed -= new EventHandler(UpdateTreeBounds);
+      }
+
+      // remove the operator from the allowed sub-functions of the remaining operators
+      foreach(IOperator o in Operators) {
+        if(o != op) {
+          foreach(IConstraint c in o.Constraints) {
+            if(c is SubOperatorTypeConstraint) {
+              ((SubOperatorTypeConstraint)c).RemoveOperator(op);
+            } else if(c is AllSubOperatorsTypeConstraint) {
+              ((AllSubOperatorsTypeConstraint)c).RemoveOperator(op);
+            }
+          }
+        }
+      }
+      OnOperatorRemoved(op);
+    }
+
+    public override void RemoveSubGroup(IOperatorGroup group) {
+      throw new NotSupportedException();
+    }
+
+    public event EventHandler OperatorAdded;
+    public event EventHandler OperatorRemoved;
+
+    protected virtual void OnOperatorAdded(IOperator op) {
+      if(OperatorAdded != null) {
+        OperatorAdded(this, new OperatorEventArgs(op));
+      }
+    }
+    protected virtual void OnOperatorRemoved(IOperator op) {
+      if(OperatorRemoved != null) {
+        OperatorRemoved(this, new OperatorEventArgs(op));
+      }
+    }
+  }
+
+  internal class OperatorEventArgs : EventArgs {
+    public IOperator op;
+
+    public OperatorEventArgs(IOperator op) {
+      this.op = op;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/GPOperatorLibrary.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/GPOperatorLibrary.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/GPOperatorLibrary.cs	(revision 656)
@@ -0,0 +1,86 @@
+#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.Core;
+using System.Xml;
+
+namespace HeuristicLab.GP {
+  public class GPOperatorLibrary : ItemBase, IOperatorLibrary, IEditable  {
+    // constants for variable names
+    internal const string MIN_TREE_HEIGHT = "MinTreeHeight";
+    internal const string MIN_TREE_SIZE = "MinTreeSize";
+    internal const string TICKETS = "Tickets";
+
+    private GPOperatorGroup group;
+
+    public GPOperatorGroup GPOperatorGroup {
+      get { return group; }
+    }
+    #region IOperatorLibrary Members
+
+    public IOperatorGroup Group {
+      get { return group; }
+    }
+
+    #endregion
+
+
+    public GPOperatorLibrary()
+      : base() {
+      group = new GPOperatorGroup();
+    }
+
+    public override IView CreateView() {
+      return new GPOperatorLibraryEditor(this);
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      GPOperatorLibrary clone = (GPOperatorLibrary)base.Clone(clonedObjects);
+      clone.group = (GPOperatorGroup)group.Clone(clonedObjects);
+      return clone;
+    }
+
+    #region persistence
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      node.AppendChild(PersistenceManager.Persist("Group", group, document, persistedObjects));
+      return node;
+    }
+
+    public override void Populate(System.Xml.XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      group = (GPOperatorGroup) PersistenceManager.Restore(node.SelectSingleNode("Group"), restoredObjects);
+    }
+    #endregion
+
+    #region IEditable Members
+
+    public IEditor CreateEditor() {
+      return new GPOperatorLibraryEditor(this);
+    }
+
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.Designer.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.Designer.cs	(revision 656)
@@ -0,0 +1,238 @@
+#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
+
+namespace HeuristicLab.GP {
+  partial class GPOperatorLibraryEditor {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if(disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.operatorLibraryEditor = new HeuristicLab.Core.OperatorLibraryEditor();
+      this.tabControl = new System.Windows.Forms.TabControl();
+      this.operatorLibraryTabPage = new System.Windows.Forms.TabPage();
+      this.initializationTabPage = new System.Windows.Forms.TabPage();
+      this.initSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.initListView = new System.Windows.Forms.ListView();
+      this.initVariableView = new HeuristicLab.Core.VariableView();
+      this.mutationTabPage = new System.Windows.Forms.TabPage();
+      this.mutationSplitContainer = new System.Windows.Forms.SplitContainer();
+      this.mutationListView = new System.Windows.Forms.ListView();
+      this.mutationVariableView = new HeuristicLab.Core.VariableView();
+      this.tabControl.SuspendLayout();
+      this.operatorLibraryTabPage.SuspendLayout();
+      this.initializationTabPage.SuspendLayout();
+      this.initSplitContainer.Panel1.SuspendLayout();
+      this.initSplitContainer.Panel2.SuspendLayout();
+      this.initSplitContainer.SuspendLayout();
+      this.mutationTabPage.SuspendLayout();
+      this.mutationSplitContainer.Panel1.SuspendLayout();
+      this.mutationSplitContainer.Panel2.SuspendLayout();
+      this.mutationSplitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // operatorLibraryEditor
+      // 
+      this.operatorLibraryEditor.Caption = "Operator Library";
+      this.operatorLibraryEditor.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.operatorLibraryEditor.Filename = null;
+      this.operatorLibraryEditor.Location = new System.Drawing.Point(3, 3);
+      this.operatorLibraryEditor.Name = "operatorLibraryEditor";
+      this.operatorLibraryEditor.OperatorLibrary = null;
+      this.operatorLibraryEditor.Size = new System.Drawing.Size(663, 529);
+      this.operatorLibraryEditor.TabIndex = 0;
+      // 
+      // tabControl
+      // 
+      this.tabControl.Controls.Add(this.operatorLibraryTabPage);
+      this.tabControl.Controls.Add(this.initializationTabPage);
+      this.tabControl.Controls.Add(this.mutationTabPage);
+      this.tabControl.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.tabControl.Location = new System.Drawing.Point(0, 0);
+      this.tabControl.Name = "tabControl";
+      this.tabControl.SelectedIndex = 0;
+      this.tabControl.Size = new System.Drawing.Size(677, 561);
+      this.tabControl.TabIndex = 1;
+      // 
+      // operatorLibraryTabPage
+      // 
+      this.operatorLibraryTabPage.Controls.Add(this.operatorLibraryEditor);
+      this.operatorLibraryTabPage.Location = new System.Drawing.Point(4, 22);
+      this.operatorLibraryTabPage.Name = "operatorLibraryTabPage";
+      this.operatorLibraryTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.operatorLibraryTabPage.Size = new System.Drawing.Size(669, 535);
+      this.operatorLibraryTabPage.TabIndex = 0;
+      this.operatorLibraryTabPage.Text = "Operator Library";
+      this.operatorLibraryTabPage.UseVisualStyleBackColor = true;
+      // 
+      // initializationTabPage
+      // 
+      this.initializationTabPage.Controls.Add(this.initSplitContainer);
+      this.initializationTabPage.Location = new System.Drawing.Point(4, 22);
+      this.initializationTabPage.Name = "initializationTabPage";
+      this.initializationTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.initializationTabPage.Size = new System.Drawing.Size(669, 535);
+      this.initializationTabPage.TabIndex = 1;
+      this.initializationTabPage.Text = "Initialization";
+      this.initializationTabPage.UseVisualStyleBackColor = true;
+      // 
+      // initSplitContainer
+      // 
+      this.initSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.initSplitContainer.Location = new System.Drawing.Point(3, 3);
+      this.initSplitContainer.Name = "initSplitContainer";
+      // 
+      // initSplitContainer.Panel1
+      // 
+      this.initSplitContainer.Panel1.Controls.Add(this.initListView);
+      // 
+      // initSplitContainer.Panel2
+      // 
+      this.initSplitContainer.Panel2.Controls.Add(this.initVariableView);
+      this.initSplitContainer.Size = new System.Drawing.Size(663, 529);
+      this.initSplitContainer.SplitterDistance = 221;
+      this.initSplitContainer.TabIndex = 0;
+      // 
+      // initListView
+      // 
+      this.initListView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.initListView.Location = new System.Drawing.Point(0, 0);
+      this.initListView.Name = "initListView";
+      this.initListView.Size = new System.Drawing.Size(221, 529);
+      this.initListView.TabIndex = 0;
+      this.initListView.UseCompatibleStateImageBehavior = false;
+      this.initListView.View = System.Windows.Forms.View.List;
+      this.initListView.SelectedIndexChanged += new System.EventHandler(this.initListView_SelectedIndexChanged);
+      // 
+      // initVariableView
+      // 
+      this.initVariableView.Caption = "Variable";
+      this.initVariableView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.initVariableView.Location = new System.Drawing.Point(0, 0);
+      this.initVariableView.Name = "initVariableView";
+      this.initVariableView.Size = new System.Drawing.Size(438, 529);
+      this.initVariableView.TabIndex = 0;
+      this.initVariableView.Variable = null;
+      // 
+      // mutationTabPage
+      // 
+      this.mutationTabPage.Controls.Add(this.mutationSplitContainer);
+      this.mutationTabPage.Location = new System.Drawing.Point(4, 22);
+      this.mutationTabPage.Name = "mutationTabPage";
+      this.mutationTabPage.Padding = new System.Windows.Forms.Padding(3);
+      this.mutationTabPage.Size = new System.Drawing.Size(669, 535);
+      this.mutationTabPage.TabIndex = 2;
+      this.mutationTabPage.Text = "Mutation";
+      this.mutationTabPage.UseVisualStyleBackColor = true;
+      // 
+      // mutationSplitContainer
+      // 
+      this.mutationSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.mutationSplitContainer.Location = new System.Drawing.Point(3, 3);
+      this.mutationSplitContainer.Name = "mutationSplitContainer";
+      // 
+      // mutationSplitContainer.Panel1
+      // 
+      this.mutationSplitContainer.Panel1.Controls.Add(this.mutationListView);
+      // 
+      // mutationSplitContainer.Panel2
+      // 
+      this.mutationSplitContainer.Panel2.Controls.Add(this.mutationVariableView);
+      this.mutationSplitContainer.Size = new System.Drawing.Size(663, 529);
+      this.mutationSplitContainer.SplitterDistance = 221;
+      this.mutationSplitContainer.TabIndex = 0;
+      // 
+      // mutationListView
+      // 
+      this.mutationListView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.mutationListView.Location = new System.Drawing.Point(0, 0);
+      this.mutationListView.MultiSelect = false;
+      this.mutationListView.Name = "mutationListView";
+      this.mutationListView.Size = new System.Drawing.Size(221, 529);
+      this.mutationListView.TabIndex = 0;
+      this.mutationListView.UseCompatibleStateImageBehavior = false;
+      this.mutationListView.View = System.Windows.Forms.View.List;
+      this.mutationListView.SelectedIndexChanged += new System.EventHandler(this.mutationListView_SelectedIndexChanged);
+      // 
+      // mutationVariableView
+      // 
+      this.mutationVariableView.Caption = "Variable";
+      this.mutationVariableView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.mutationVariableView.Location = new System.Drawing.Point(0, 0);
+      this.mutationVariableView.Name = "mutationVariableView";
+      this.mutationVariableView.Size = new System.Drawing.Size(438, 529);
+      this.mutationVariableView.TabIndex = 0;
+      this.mutationVariableView.Variable = null;
+      // 
+      // GPOperatorLibraryEditor
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.tabControl);
+      this.Name = "GPOperatorLibraryEditor";
+      this.Size = new System.Drawing.Size(677, 561);
+      this.tabControl.ResumeLayout(false);
+      this.operatorLibraryTabPage.ResumeLayout(false);
+      this.initializationTabPage.ResumeLayout(false);
+      this.initSplitContainer.Panel1.ResumeLayout(false);
+      this.initSplitContainer.Panel2.ResumeLayout(false);
+      this.initSplitContainer.ResumeLayout(false);
+      this.mutationTabPage.ResumeLayout(false);
+      this.mutationSplitContainer.Panel1.ResumeLayout(false);
+      this.mutationSplitContainer.Panel2.ResumeLayout(false);
+      this.mutationSplitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Core.OperatorLibraryEditor operatorLibraryEditor;
+    private System.Windows.Forms.TabControl tabControl;
+    private System.Windows.Forms.TabPage operatorLibraryTabPage;
+    private System.Windows.Forms.TabPage initializationTabPage;
+    private System.Windows.Forms.TabPage mutationTabPage;
+    private System.Windows.Forms.SplitContainer initSplitContainer;
+    private System.Windows.Forms.SplitContainer mutationSplitContainer;
+    private HeuristicLab.Core.VariableView initVariableView;
+    private HeuristicLab.Core.VariableView mutationVariableView;
+    private System.Windows.Forms.ListView initListView;
+    private System.Windows.Forms.ListView mutationListView;
+  }
+}
Index: trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.cs	(revision 656)
@@ -0,0 +1,153 @@
+#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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using System.Diagnostics;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.GP {
+  public partial class GPOperatorLibraryEditor : EditorBase {
+    public IOperatorLibrary OperatorLibrary {
+      get { return (IOperatorLibrary)Item; }
+      set { base.Item = value; }
+    }
+
+    public GPOperatorLibraryEditor(GPOperatorLibrary library)
+      : base() {
+      InitializeComponent();
+      OperatorLibrary = library;
+      operatorLibraryEditor.OperatorLibrary = library;
+
+      library.GPOperatorGroup.OperatorAdded += new EventHandler(GPOperatorLibraryView_OperatorAdded);
+      library.GPOperatorGroup.OperatorRemoved += new EventHandler(GPOperatorGroup_OperatorRemoved);
+
+      mutationVariableView.Enabled = false;
+      initVariableView.Enabled = false;
+
+      foreach(IOperator op in library.Group.Operators) {
+        if(op.GetVariable(FunctionBase.MANIPULATION) != null) {
+          ListViewItem item = new ListViewItem();
+          item.Text = op.Name;
+          item.Name = op.Name;
+          item.Tag = op;
+          mutationListView.Items.Add(item);
+        }
+        if(op.GetVariable(FunctionBase.INITIALIZATION) != null) {
+          ListViewItem item = new ListViewItem();
+          item.Name = op.Name;
+          item.Text = op.Name;
+          item.Tag = op;
+          initListView.Items.Add(item);
+        }
+      }
+    }
+
+
+    private void GPOperatorLibraryView_OperatorAdded(object sender, EventArgs e) {
+      IOperator op = ((OperatorEventArgs)e).op;
+      if(op.GetVariable(FunctionBase.MANIPULATION) != null) {
+        ListViewItem operatorMutationItem = new ListViewItem();
+        operatorMutationItem.Name = op.Name;
+        operatorMutationItem.Text = op.Name;
+        operatorMutationItem.Tag = op;
+        mutationListView.Items.Add(operatorMutationItem);
+      }
+
+      if(op.GetVariable(FunctionBase.INITIALIZATION) != null) {
+        ListViewItem operatorInitItem = new ListViewItem();
+        operatorInitItem.Name = op.Name;
+        operatorInitItem.Text = op.Name;
+        operatorInitItem.Tag = op;
+        initListView.Items.Add(operatorInitItem);
+      }
+
+      op.NameChanged += new EventHandler(op_NameChanged);
+      Refresh();
+    }
+
+    private void op_NameChanged(object sender, EventArgs e) {
+      IOperator srcOp = (IOperator)sender;
+      foreach(ListViewItem item in mutationListView.Items) {
+        if(item.Tag == srcOp) {
+          item.Name = srcOp.Name;
+          item.Text = srcOp.Name;
+          break;
+        }
+      }
+      foreach(ListViewItem item in initListView.Items) {
+        if(item.Tag == srcOp) {
+          item.Name = srcOp.Name;
+          item.Text = srcOp.Name;
+          break;
+        }
+      }
+    }
+
+
+    private void GPOperatorGroup_OperatorRemoved(object sender, EventArgs e) {
+      IOperator op = ((OperatorEventArgs)e).op;
+
+      foreach(ListViewItem item in mutationListView.Items) {
+        if(item.Tag == op) {
+          mutationListView.Items.Remove(item);
+          break;
+        }
+      }
+
+      foreach(ListViewItem item in initListView.Items) {
+        if(item.Tag == op) {
+          initListView.Items.Remove(item);
+          break;
+        }
+      }
+    }
+
+    private void mutationListView_SelectedIndexChanged(object sender, EventArgs e) {
+      if(mutationListView.SelectedItems.Count>0 && mutationListView.SelectedItems[0].Tag != null) {
+        IVariable variable = ((IOperator)mutationListView.SelectedItems[0].Tag).GetVariable(FunctionBase.MANIPULATION);
+        mutationVariableView.Enabled = true;
+        mutationVariableView.Variable = variable;
+      } else {
+        mutationVariableView.Enabled = false;
+      }
+    }
+
+    private void initListView_SelectedIndexChanged(object sender, EventArgs e) {
+      if(initListView.SelectedItems.Count>0 && initListView.SelectedItems[0].Tag != null) {
+        IVariable variable = ((IOperator)initListView.SelectedItems[0].Tag).GetVariable(FunctionBase.INITIALIZATION);
+        initVariableView.Enabled = true;
+        initVariableView.Variable = variable;
+      } else {
+        initVariableView.Enabled = false;
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.resx
===================================================================
--- trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.resx	(revision 656)
+++ trunk/sources/HeuristicLab.GP/GPOperatorLibraryEditor.resx	(revision 656)
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: trunk/sources/HeuristicLab.GP/HeuristicLab.GP.csproj
===================================================================
--- trunk/sources/HeuristicLab.GP/HeuristicLab.GP.csproj	(revision 656)
+++ trunk/sources/HeuristicLab.GP/HeuristicLab.GP.csproj	(revision 656)
@@ -0,0 +1,161 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<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.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{1F1CF3ED-374C-4288-995B-93F6B872F571}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP</RootNamespace>
+    <AssemblyName>HeuristicLab.GP-3.2</AssemblyName>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </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="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BakedFunctionTree.cs" />
+    <Compile Include="DefaultFunctionTreeNameGenerator.cs" />
+    <Compile Include="UnknownFunctionException.cs" />
+    <Compile Include="IFunctionTreeNameGenerator.cs" />
+    <Compile Include="IFunctionTreeExporter.cs" />
+    <Compile Include="FunctionBase.cs" />
+    <Compile Include="FunctionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FunctionView.Designer.cs">
+      <DependentUpon>FunctionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="GPOperatorGroup.cs" />
+    <Compile Include="GPOperatorLibrary.cs" />
+    <Compile Include="GPOperatorLibraryEditor.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="GPOperatorLibraryEditor.Designer.cs">
+      <DependentUpon>GPOperatorLibraryEditor.cs</DependentUpon>
+    </Compile>
+    <Compile Include="HeuristicLabGPPlugin.cs" />
+    <Compile Include="IFunction.cs" />
+    <Compile Include="IFunctionTree.cs" />
+    <Compile Include="Manipulation\ChangeNodeTypeManipulation.cs" />
+    <Compile Include="Manipulation\CutOutNodeManipulation.cs" />
+    <Compile Include="Manipulation\DeleteSubTreeManipulation.cs" />
+    <Compile Include="Manipulation\FullTreeShaker.cs" />
+    <Compile Include="Manipulation\OnePointShaker.cs" />
+    <Compile Include="Manipulation\SubstituteSubTreeManipulation.cs" />
+    <Compile Include="ProbabilisticTreeCreator.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RampedTreeCreator.cs" />
+    <Compile Include="Recombination\LangdonHomologousCrossOver.cs" />
+    <Compile Include="Recombination\OnePointCrossOver.cs" />
+    <Compile Include="Recombination\SizeFairCrossOver.cs" />
+    <Compile Include="Recombination\StandardCrossOver.cs" />
+    <Compile Include="TreeGardener.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\HeuristicLab.Constraints\HeuristicLab.Constraints.csproj">
+      <Project>{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}</Project>
+      <Name>HeuristicLab.Constraints</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Core\HeuristicLab.Core.csproj">
+      <Project>{F43B59AB-2B8C-4570-BC1E-15592086517C}</Project>
+      <Name>HeuristicLab.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Data\HeuristicLab.Data.csproj">
+      <Project>{F473D9AF-3F09-4296-9F28-3C65118DAFFA}</Project>
+      <Name>HeuristicLab.Data</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Operators\HeuristicLab.Operators.csproj">
+      <Project>{A9983BA2-B3B2-475E-8E2C-62050B71D1C5}</Project>
+      <Name>HeuristicLab.Operators</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.PluginInfrastructure\HeuristicLab.PluginInfrastructure.csproj">
+      <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project>
+      <Name>HeuristicLab.PluginInfrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Random\HeuristicLab.Random.csproj">
+      <Project>{47019A74-F7F7-482E-83AA-D3F4F777E879}</Project>
+      <Name>HeuristicLab.Random</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\HeuristicLab.Selection\HeuristicLab.Selection.csproj">
+      <Project>{F7CF0571-25CB-43D5-8443-0843A1E2861A}</Project>
+      <Name>HeuristicLab.Selection</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="FunctionView.resx">
+      <DependentUpon>FunctionView.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+    <EmbeddedResource Include="GPOperatorLibraryEditor.resx">
+      <DependentUpon>GPOperatorLibraryEditor.cs</DependentUpon>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.frame" />
+  </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>cmd /c ""$(SolutionDir)PreBuildEvent.cmd" "$(ProjectDir).""</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: trunk/sources/HeuristicLab.GP/HeuristicLabGPPlugin.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/HeuristicLabGPPlugin.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/HeuristicLabGPPlugin.cs	(revision 656)
@@ -0,0 +1,38 @@
+#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.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.GP {
+  [ClassInfo(Name = "HeuristicLab.GP-3.2")]
+  [PluginFile(Filename = "HeuristicLab.GP-3.2.dll", Filetype = PluginFileType.Assembly)]
+  [Dependency(Dependency = "HeuristicLab.Constraints-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Core-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Data-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Operators-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Random-3.2")]
+  [Dependency(Dependency = "HeuristicLab.Selection-3.2")]
+  public class HeuristicLabGPPlugin : PluginBase {
+  }
+}
Index: trunk/sources/HeuristicLab.GP/IFunction.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/IFunction.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/IFunction.cs	(revision 656)
@@ -0,0 +1,35 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public interface IFunction : IOperator {
+    IFunctionTree GetTreeNode();
+    double Apply();
+    IList<IFunction> AllowedSubFunctions(int index);
+    int MinArity { get; }
+    int MaxArity { get; }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/IFunctionTree.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/IFunctionTree.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/IFunctionTree.cs	(revision 656)
@@ -0,0 +1,41 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public interface IFunctionTree : IItem {
+    int Size { get; }
+    int Height { get; }
+    IList<IFunctionTree> SubTrees { get; }
+    ICollection<IVariable> LocalVariables { get; }
+    IFunction Function { get; }
+    IVariable GetLocalVariable(string name);
+    void AddVariable(IVariable variable);
+    void RemoveVariable(string name);
+    void AddSubTree(IFunctionTree tree);
+    void InsertSubTree(int index, IFunctionTree tree);
+    void RemoveSubTree(int index);
+  }
+}
Index: trunk/sources/HeuristicLab.GP/IFunctionTreeExporter.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/IFunctionTreeExporter.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/IFunctionTreeExporter.cs	(revision 656)
@@ -0,0 +1,33 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public interface IFunctionTreeExporter {
+    string Name { get; }
+    string Export(IFunctionTree tree);
+    bool TryExport(IFunctionTree tree, out string exported);
+  }
+}
Index: trunk/sources/HeuristicLab.GP/IFunctionTreeNameGenerator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/IFunctionTreeNameGenerator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/IFunctionTreeNameGenerator.cs	(revision 656)
@@ -0,0 +1,32 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public interface IFunctionTreeNameGenerator {
+    string Name { get; }
+    string GetName(IFunctionTree tree);
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/ChangeNodeTypeManipulation.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/ChangeNodeTypeManipulation.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/ChangeNodeTypeManipulation.cs	(revision 656)
@@ -0,0 +1,192 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class ChangeNodeTypeManipulation : OperatorBase {
+
+    public override string Description {
+      get {
+        return @"This manipulation operator selects a random tree-node and changes the function type.
+If this leads to a constraint-violation (wrong number or type of sub-trees) the sub-trees are repaired
+resulting in a valid tree again.";
+      }
+    }
+
+    public ChangeNodeTypeManipulation()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+    }
+
+
+    public override IOperation Apply(IScope scope) {
+      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, false);
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      IntData treeSize = GetVariableValue<IntData>("TreeSize", scope, false);
+      IntData treeHeight = GetVariableValue<IntData>("TreeHeight", scope, false);
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      TreeGardener gardener = new TreeGardener(random, library);
+      IFunctionTree parent = gardener.GetRandomParentNode(root);
+      IFunctionTree selectedChild;
+      int selectedChildIndex;
+      if(parent == null) {
+        selectedChildIndex = 0;
+        selectedChild = root;
+      } else {
+        selectedChildIndex = random.Next(parent.SubTrees.Count);
+        selectedChild = parent.SubTrees[selectedChildIndex];
+      }
+
+      if(selectedChild.SubTrees.Count == 0) {
+        IFunctionTree newTerminal = ChangeTerminalType(parent, selectedChild, selectedChildIndex, gardener, random);
+        if(parent == null) {
+          // no parent means the new child is the initial operator
+          // and we have to update the value in the variable
+          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTerminal;
+        } else {
+          parent.RemoveSubTree(selectedChildIndex);
+          parent.InsertSubTree(selectedChildIndex, newTerminal);
+          // updating the variable is not necessary because it stays the same
+        }
+        Debug.Assert(gardener.IsValidTree(root));
+        // size and height stays the same when changing a terminal so no need to update the variables
+        // schedule an operation to initialize the new terminal
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTerminal), scope);
+      } else {
+        List<IFunctionTree> uninitializedBranches;
+        IFunctionTree newFunctionTree = ChangeFunctionType(parent, selectedChild, selectedChildIndex, gardener, random, out uninitializedBranches);
+        // in rare cases the function creates a tree that breaks the size limits
+        // calculate the height and size difference and 
+        // check if the size of the new tree is still in the allowed bounds
+        int oldChildSize = selectedChild.Size;
+        int oldChildHeight = selectedChild.Height;
+        int newChildSize = newFunctionTree.Size;
+        int newChildHeight = newFunctionTree.Height;
+        if((treeHeight.Data - oldChildHeight) + newChildHeight > maxTreeHeight ||
+          (treeSize.Data - oldChildSize) + newChildSize > maxTreeSize) {
+          // if size-constraints are violated don't change anything
+          return null;
+        }
+        if(parent == null) {
+          // no parent means the new function is the initial operator
+          // and we have to update the value in the variable
+          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newFunctionTree;
+          root = newFunctionTree;
+        } else {
+          // remove the old child
+          parent.RemoveSubTree(selectedChildIndex);
+          // add the new child as sub-tree of parent
+          parent.InsertSubTree(selectedChildIndex, newFunctionTree);
+        }
+        // update size and height
+        treeSize.Data = (treeSize.Data - oldChildSize) + newChildSize;
+        treeHeight.Data = root.Height; // must recalculate height because we can't know wether the manipulated branch was the deepest branch
+        // check if whole tree is ok
+        Debug.Assert(gardener.IsValidTree(root));
+        // return a composite operation that initializes all created sub-trees
+        return gardener.CreateInitializationOperation(uninitializedBranches, scope);
+      }
+    }
+  
+
+    private IFunctionTree ChangeTerminalType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random) {
+      IList<IFunction> allowedTerminals;
+      if (parent == null) {
+        allowedTerminals = gardener.Terminals;
+      } else {
+        allowedTerminals = new List<IFunction>();
+        var allAllowedChildren = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
+        foreach(IFunction c in allAllowedChildren) {
+          if(gardener.IsTerminal(c)) allowedTerminals.Add(c);
+        }
+      }
+      // selecting from the terminals should always work since the current child was also a terminal
+      // so in the worst case we will just create a new terminal of the same type again.
+      return gardener.CreateRandomTree(allowedTerminals, 1, 1);
+    }
+
+    private IFunctionTree ChangeFunctionType(IFunctionTree parent, IFunctionTree child, int childIndex, TreeGardener gardener, MersenneTwister random,
+      out List<IFunctionTree> uninitializedBranches) {
+      // since there are subtrees, we have to check which 
+      // and how many of the existing subtrees we can reuse.
+      // first let's choose the function we want to use instead of the old child. For this we have to determine the
+      // pool of allowed functions based on constraints of the parent if there is one.
+      IList<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent!=null?parent.Function:null, childIndex);
+      // try to make a tree with the same arity as the old child.
+      int actualArity = child.SubTrees.Count;
+      // create a new tree-node for a randomly selected function
+      IFunction selectedFunction = allowedFunctions[random.Next(allowedFunctions.Count)];
+      // arity of the selected operator
+      int minArity = selectedFunction.MinArity;
+      int maxArity = selectedFunction.MaxArity;
+      // if the old child had too many sub-trees then the new child should keep as many sub-trees as possible
+      if (actualArity > maxArity)
+        actualArity = maxArity;
+      if(actualArity < minArity)
+        actualArity = minArity;
+      // create a list that holds old sub-trees that we can reuse in the new tree
+      List<IFunctionTree> availableSubTrees = new List<IFunctionTree>(child.SubTrees);
+      List<IFunctionTree> freshSubTrees = new List<IFunctionTree>();
+      IFunctionTree newTree = selectedFunction.GetTreeNode();
+      // randomly select the sub-trees that we keep
+      for (int i = 0; i < actualArity; i++) {
+        // fill all sub-tree slots of the new tree
+        // if for a given slot i there are multiple existing sub-trees that can be used in that slot
+        // then use a random existing sub-tree. When there are no existing sub-trees
+        // that fit in the given slot then create a new random tree and use it for the slot
+        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(selectedFunction, i);
+        var matchingSubTrees = availableSubTrees.Where(subTree => allowedSubFunctions.Contains(subTree.Function));
+        if (matchingSubTrees.Count() > 0) {
+          IFunctionTree selectedSubTree = matchingSubTrees.ElementAt(random.Next(matchingSubTrees.Count()));
+          // we can just add it as subtree
+          newTree.InsertSubTree(i, selectedSubTree);
+          availableSubTrees.Remove(selectedSubTree); // the branch shouldn't be available for the following slots
+        } else {
+          // no existing matching tree found => create a new tree of minimal size
+          IFunctionTree freshTree = gardener.CreateRandomTree(allowedSubFunctions, 1, 1);
+          freshSubTrees.AddRange(gardener.GetAllSubTrees(freshTree));
+          newTree.InsertSubTree(i, freshTree);
+        }
+      }
+      freshSubTrees.Add(newTree);
+      uninitializedBranches = freshSubTrees;
+      return newTree;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/CutOutNodeManipulation.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/CutOutNodeManipulation.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/CutOutNodeManipulation.cs	(revision 656)
@@ -0,0 +1,131 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using System;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class CutOutNodeManipulation : OperatorBase {
+    public override string Description {
+      get {
+        return @"Takes a tree, selects a random node of the tree and then tries to replace a random sub-tree
+of that node with one of the childs of the selected child.
+
+               O                             O
+              / \                           / \
+             O   X                         O   2
+                / \    2 is selected =>       / \
+               1   2                         4   5
+              /   / \
+             3   4   5
+";
+      }
+    }
+
+    public CutOutNodeManipulation()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+    }
+
+
+    public override IOperation Apply(IScope scope) {
+      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, true);
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+      TreeGardener gardener = new TreeGardener(random, library);
+      IFunctionTree parent = gardener.GetRandomParentNode(root);
+      // parent == null means we should cut out the root node
+      // => return a random sub-tree of the root
+      if (parent == null) {
+        // when there are sub-trees then replace the old tree with a random sub-tree
+        if (root.SubTrees.Count > 0) {
+          root = root.SubTrees[random.Next(root.SubTrees.Count)];
+          GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+          GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+          // update the variable
+          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = root;
+          Debug.Assert(gardener.IsValidTree(root));
+          // we reused a sub-tree so we don't have to schedule initialization operations
+          return null;
+        } else {
+          // we want to cut the root node and there are no sub-trees => create a new random terminal
+          IFunctionTree newTree;
+          newTree = gardener.CreateRandomTree(gardener.Terminals, 1, 1);
+          GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+          GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
+          // update the variable
+          scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
+          Debug.Assert(gardener.IsValidTree(newTree));
+          // schedule an operation to initialize the whole tree
+          return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
+        }
+      }
+      // select a child to cut away
+      int childIndex = random.Next(parent.SubTrees.Count);
+      IFunctionTree child = parent.SubTrees[childIndex];
+      // match the sub-trees of the child with the allowed sub-trees of the parent
+      ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
+      IFunctionTree[] possibleChilds = child.SubTrees.Where(t => allowedFunctions.Contains(t.Function)).ToArray();
+      if (possibleChilds.Length > 0) {
+        // replace child with a random child of that child
+        IFunctionTree selectedChild = possibleChilds[random.Next(possibleChilds.Length)];        
+        parent.RemoveSubTree(childIndex);
+        parent.InsertSubTree(childIndex, selectedChild);
+        Debug.Assert(gardener.IsValidTree(root));
+        // update the size and height of our tree
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+        // don't need to schedule initialization operations
+        return null;
+      } else {
+        // can't reuse an existing branch => create a new tree
+        // determine the level of the parent
+        int parentLevel = gardener.GetBranchLevel(root, parent);
+        // first remove the old child (first step essential!)
+        parent.RemoveSubTree(childIndex);
+        // then determine the number of nodes left over after the child has been removed!
+        int remainingNodes = root.Size;
+        allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
+        IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, maxTreeSize - remainingNodes, maxTreeHeight - parentLevel);
+        parent.InsertSubTree(childIndex, newFunctionTree);
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+        Debug.Assert(gardener.IsValidTree(root));
+        // schedule an initialization operation for the new function-tree
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newFunctionTree), scope);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/DeleteSubTreeManipulation.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/DeleteSubTreeManipulation.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/DeleteSubTreeManipulation.cs	(revision 656)
@@ -0,0 +1,103 @@
+#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 HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class DeleteSubTreeManipulation : OperatorBase {
+    public override string Description {
+      get {
+        return @"Deletes a random sub-tree of the input tree. If the remaining tree is not valid 
+the operator tries to fix the tree by generating random subtrees where necessary.";
+      }
+    }
+
+    public DeleteSubTreeManipulation()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+    }
+
+
+    public override IOperation Apply(IScope scope) {
+      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, true);
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      TreeGardener gardener = new TreeGardener(random, library);
+      IFunctionTree parent = gardener.GetRandomParentNode(root);
+
+      // parent==null means the whole tree should be deleted.
+      // => return a new minimal random tree
+      if(parent == null) {
+        IFunctionTree newTree = gardener.CreateBalancedRandomTree(1, 1);
+        // check if the tree is ok
+        Debug.Assert(gardener.IsValidTree(newTree));
+        // update sizes to match the new tree
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
+        scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
+
+        // schedule an operation to initialize the newly created operator
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
+      }
+
+      // select a branch to prune
+      int childIndex = random.Next(parent.SubTrees.Count);
+      if(parent.SubTrees.Count > parent.Function.MinArity) {
+        parent.RemoveSubTree(childIndex);
+        // actually since the next sub-trees are shifted in the place of the removed branch
+        // it might be possible that these sub-trees are not allowed in the place of the old branch
+        // we ignore this problem for now.
+        // when this starts to become a problem a possible solution is to go through the shifted branches from the place of the shifted
+        // and find the first one that doesn't fit. At this position we insert a new randomly initialized subtree of matching type (gkronber 25.12.07)
+
+        Debug.Assert(gardener.IsValidTree(root));
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+        // root hasn't changed so don't need to update 'FunctionTree' variable
+        return null;
+      } else {
+        // replace with a minimal random seedling
+        parent.RemoveSubTree(childIndex);
+        ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
+        IFunctionTree newFunctionTree = gardener.CreateRandomTree(allowedFunctions, 1, 1);
+        parent.InsertSubTree(childIndex, newFunctionTree);
+        Debug.Assert(gardener.IsValidTree(root));
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+        // again the root hasn't changed so we don't need to update the 'FunctionTree' variable
+        // but we have to return an initialization operation for the newly created tree
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newFunctionTree), scope);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/FullTreeShaker.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/FullTreeShaker.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/FullTreeShaker.cs	(revision 656)
@@ -0,0 +1,87 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.GP {
+  public class FullTreeShaker : DelegatingOperator {
+    public override string Description {
+      get { return "Manipulates all tree nodes for which a '" + FunctionBase.MANIPULATION + "' variable is defined."; }
+    }
+
+    public FullTreeShaker()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "Operator library that defines operator mutations", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("ShakingFactor", "Variable that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      IFunctionTree tree = GetVariableValue<IFunctionTree>("FunctionTree", scope, false);
+      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
+
+      // enqueue all mutation operations as parallel operations
+      CompositeOperation next = new CompositeOperation();
+      next.ExecuteInParallel = true;
+
+      Scope tempScope = new Scope("Temp. manipulation scope");
+
+      TreeGardener gardener = new TreeGardener(mt, library);
+      var parametricBranches = gardener.GetAllSubTrees(tree).Where(branch => branch.Function.GetVariable(FunctionBase.MANIPULATION) != null);
+      foreach(IFunctionTree subTree in parametricBranches) {
+        IOperator mutation = (IOperator)subTree.Function.GetVariable(FunctionBase.MANIPULATION).Value;
+
+        // store all local variables into a temporary scope
+        Scope mutationScope = new Scope();
+        foreach(IVariable variable in subTree.LocalVariables) {
+          mutationScope.AddVariable(variable);
+        }
+
+        tempScope.AddSubScope(mutationScope);
+        next.AddOperation(new AtomicOperation(mutation, mutationScope));
+      }
+
+      // save all existing sub-scopes in a backup scope
+      Scope backupScope = new Scope("backup");
+      foreach(Scope subScope in scope.SubScopes) {
+        backupScope.AddSubScope(subScope);
+      }
+
+      scope.AddSubScope(tempScope); // scope containing a subscope for each manipulation
+      scope.AddSubScope(backupScope); // scope containing the old subscopes
+
+      // schedule a reducer operation to delete all temporary scopes and restore
+      // the subscopes of the backup scope after all manipulations are finished.
+      next.AddOperation(new AtomicOperation(new RightReducer(), scope));
+      return next;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/OnePointShaker.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/OnePointShaker.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/OnePointShaker.cs	(revision 656)
@@ -0,0 +1,81 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.GP {
+  public class OnePointShaker : DelegatingOperator {
+    public override string Description {
+      get { return "Selects a random node of all tree-nodes that have a '"+FunctionBase.MANIPULATION+"' variable defined and manipulates the selected node."; }
+    }
+
+    public OnePointShaker()
+      : base() {
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "Operator library that defines mutation operations for operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("Random", "A random generator (uniform)", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("ShakingFactor", "Factor that determines the force of the shaking operation", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The function tree that should be mutated", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      IFunctionTree tree = GetVariableValue<IFunctionTree>("FunctionTree", scope, false);
+      MersenneTwister mt = GetVariableValue<MersenneTwister>("Random", scope, true);
+      TreeGardener gardener = new TreeGardener(mt, library);
+
+      // get all nodes for which a manipulation is defined
+      var parametricBranches = gardener.GetAllSubTrees(tree).Where(branch => branch.Function.GetVariable(FunctionBase.MANIPULATION) != null);
+      IFunctionTree selectedBranch = parametricBranches.ElementAt(mt.Next(parametricBranches.Count()));
+      IOperator mutation = (IOperator)selectedBranch.Function.GetVariable(FunctionBase.MANIPULATION).Value;
+      CompositeOperation next = new CompositeOperation();
+
+      // store all local variables into a temporary scope
+      Scope tempScope = new Scope("Temp. manipulation scope");
+      foreach(IVariable variable in selectedBranch.LocalVariables) {
+        tempScope.AddVariable(variable);
+      }
+
+      // save the exising sub-scops in a backup scope
+      Scope backupScope = new Scope("backup");
+      foreach (Scope subScope in scope.SubScopes) {
+        backupScope.AddSubScope(subScope);
+      }
+
+      // add the new sub-scopes
+      scope.AddSubScope(tempScope);
+      scope.AddSubScope(backupScope);
+
+      // the next operation should first manipulate and then restore the sub-scopes from the backup scope
+      next.AddOperation(new AtomicOperation(mutation, tempScope));
+      next.AddOperation(new AtomicOperation(new RightReducer(), scope));
+
+      return next;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Manipulation/SubstituteSubTreeManipulation.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Manipulation/SubstituteSubTreeManipulation.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Manipulation/SubstituteSubTreeManipulation.cs	(revision 656)
@@ -0,0 +1,104 @@
+#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 HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class SubstituteSubTreeManipulation : OperatorBase {
+
+    public override string Description {
+      get { return "Selects a random node of the tree and replaces it with randomly initialized subtree."; }
+    }
+
+    public SubstituteSubTreeManipulation()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to manipulate", typeof(IFunctionTree), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.In | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IFunctionTree root = GetVariableValue<IFunctionTree>("FunctionTree", scope, true);
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary library = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+      int treeSize = GetVariableValue<IntData>("TreeSize", scope, true).Data;
+      int treeHeight = GetVariableValue<IntData>("TreeHeight", scope, true).Data;
+      TreeGardener gardener = new TreeGardener(random, library);
+      IFunctionTree parent = gardener.GetRandomParentNode(root);
+      if(parent == null) {
+        // parent == null means we should subsitute the whole tree
+        // => create a new random tree
+        IFunctionTree newTree = gardener.CreateRandomTree(gardener.AllFunctions, maxTreeSize, maxTreeHeight);
+        Debug.Assert(gardener.IsValidTree(newTree));
+
+        // update the variables in the scope with the new values
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = newTree.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = newTree.Height;
+        scope.GetVariable(scope.TranslateName("FunctionTree")).Value = newTree;
+        
+        // return a CompositeOperation that randomly initializes the new tree
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
+      } else {
+        // determine a random child of the parent to be replaced
+        int childIndex = random.Next(parent.SubTrees.Count);
+        // get the list of allowed functions for the new sub-tree
+        ICollection<IFunction> allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, childIndex);
+        if(allowedFunctions.Count == 0) {
+          // don't change anything
+          // this shouldn't happen
+          throw new InvalidProgramException();
+        }
+
+        // calculate the maximum size and height of the new sub-tree based on the location where
+        // it will be inserted
+        int parentLevel = gardener.GetBranchLevel(root, parent);
+        int maxSubTreeHeight = maxTreeHeight - parentLevel;
+        int maxSubTreeSize = maxTreeSize - (treeSize - parent.SubTrees[childIndex].Size);
+
+        // create a random function tree
+        IFunctionTree newTree = gardener.CreateRandomTree(allowedFunctions, maxSubTreeSize, maxSubTreeHeight);
+        parent.RemoveSubTree(childIndex);
+        parent.InsertSubTree(childIndex, newTree);
+
+        Debug.Assert(gardener.IsValidTree(root));
+        // update the values of treeSize and treeHeight
+        GetVariableValue<IntData>("TreeSize", scope, true).Data = root.Size;
+        GetVariableValue<IntData>("TreeHeight", scope, true).Data = root.Height;
+        // the root hasn't changed so we don't need to update 
+        // return a CompositeOperation that randomly initializes all nodes of the new subtree
+        return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(newTree), scope);
+      }
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/ProbabilisticTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/ProbabilisticTreeCreator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/ProbabilisticTreeCreator.cs	(revision 656)
@@ -0,0 +1,72 @@
+#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.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using System;
+using HeuristicLab.Random;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class ProbabilisticTreeCreator : OperatorBase {
+    public override string Description {
+      get { return @"Generates a new random operator tree."; }
+    }
+
+    public ProbabilisticTreeCreator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTreeSize", "The minimal allowed size of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IFunctionTree), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int minTreeSize = GetVariableValue<IntData>("MinTreeSize", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      int treeSize = random.Next(minTreeSize, maxTreeSize + 1);
+      IFunctionTree root = gardener.PTC2(random, treeSize, maxTreeHeight);
+
+      int actualTreeSize = root.Size;
+      int actualTreeHeight = root.Height;
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(actualTreeSize)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(actualTreeHeight)));
+
+      Debug.Assert(gardener.IsValidTree(root) && actualTreeHeight<=maxTreeHeight);
+
+      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Properties/AssemblyInfo.frame
===================================================================
--- trunk/sources/HeuristicLab.GP/Properties/AssemblyInfo.frame	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Properties/AssemblyInfo.frame	(revision 656)
@@ -0,0 +1,58 @@
+#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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using HeuristicLab.PluginInfrastructure;
+
+// 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")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2008 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("863021a4-3cde-48be-8af6-dac1077f5fb5")]
+
+// 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.2.0.$WCREV$")]
+[assembly: AssemblyFileVersion("3.2.0.$WCREV$")]
+[assembly: AssemblyBuildDate("$WCNOW$")]
Index: trunk/sources/HeuristicLab.GP/RampedTreeCreator.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/RampedTreeCreator.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/RampedTreeCreator.cs	(revision 656)
@@ -0,0 +1,77 @@
+#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.Linq;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using System;
+using HeuristicLab.Random;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class RampedTreeCreator : OperatorBase {
+    public override string Description {
+      get { return @"Generates a new random operator tree."; }
+    }
+
+    public RampedTreeCreator()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Uniform random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MinTreeHeight", "The minimal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("BalancedTreesRate", "Determines how many trees should be balanced", typeof(DoubleData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The created tree", typeof(IFunctionTree), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New | VariableKind.Out));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      IRandom random = GetVariableValue<IRandom>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int minTreeHeight = GetVariableValue<IntData>("MinTreeHeight", scope, true).Data;
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      double balancedTreesRate = GetVariableValue<DoubleData>("BalancedTreesRate", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      int treeHeight = random.Next(minTreeHeight, maxTreeHeight + 1);
+      IFunctionTree root;
+      if(random.NextDouble() <= balancedTreesRate) {
+        root = gardener.CreateBalancedRandomTree(Int32.MaxValue, treeHeight);
+      } else {
+        root = gardener.CreateUnbalancedRandomTree(Int32.MaxValue, treeHeight);
+      }
+
+      int actualTreeSize = root.Size;
+      int actualTreeHeight = root.Height;
+
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), root));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(actualTreeSize)));
+      scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(actualTreeHeight)));
+
+      Debug.Assert(gardener.IsValidTree(root) && actualTreeHeight <= maxTreeHeight);
+
+      return gardener.CreateInitializationOperation(gardener.GetAllSubTrees(root), scope);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Recombination/LangdonHomologousCrossOver.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Recombination/LangdonHomologousCrossOver.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Recombination/LangdonHomologousCrossOver.cs	(revision 656)
@@ -0,0 +1,295 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  /// <summary>
+  /// Implementation of a homologous crossover operator as described in: 
+  /// William B. Langdon 
+  /// Size Fair and Homologous Tree Genetic Programming Crossovers, 
+  /// Genetic Programming and Evolvable Machines, Vol. 1, Number 1/2, pp. 95-119, April 2000
+  /// </summary>
+  public class LangdonHomologousCrossOver : OperatorBase {
+    private const int MAX_RECOMBINATION_TRIES = 20;
+    public override string Description {
+      get {
+        return @"";
+      }
+    }
+    public LangdonHomologousCrossOver()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      if((scope.SubScopes.Count % 2) != 0)
+        throw new InvalidOperationException("Number of parents is not even");
+
+      CompositeOperation initOperations = new CompositeOperation();
+
+      int children = scope.SubScopes.Count / 2;
+      for(int i = 0; i < children; i++) {
+        IScope parent1 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent1);
+        IScope parent2 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent2);
+        IScope child = new Scope(i.ToString());
+        IOperation childInitOperation = Cross(gardener, maxTreeSize, maxTreeHeight, scope, random, parent1, parent2, child);
+        initOperations.AddOperation(childInitOperation);
+        scope.AddSubScope(child);
+      }
+
+      return initOperations;
+    }
+
+    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
+      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
+      List<IFunctionTree> newBranches;
+      IFunctionTree newTree = Cross(gardener, parent1, parent2,
+        random, maxTreeSize, maxTreeHeight, out newBranches);
+
+
+      int newTreeSize = newTree.Size;
+      int newTreeHeight = newTree.Height;
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight)));
+
+      // check if the new tree is valid and if the height of is still in the allowed bounds (we are not so strict for the max-size)
+      Debug.Assert(gardener.IsValidTree(newTree) && newTreeHeight <= maxTreeHeight && newTreeSize <= maxTreeSize);
+      return gardener.CreateInitializationOperation(newBranches, child);
+    }
+
+
+    private IFunctionTree Cross(TreeGardener gardener, IScope f, IScope g, MersenneTwister random, int maxTreeSize, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      if(tree0Size == 1 && tree1Size == 1) {
+        return CombineTerminals(gardener, tree0, tree1, random, maxTreeHeight, out newBranches);
+      } else {
+        newBranches = new List<IFunctionTree>();
+
+        // we are going to insert tree1 into tree0 at a random place so we have to make sure that tree0 is not a terminal
+        // in case both trees are higher than 1 we swap the trees with probability 50%
+        if(tree0Height == 1 || (tree1Height > 1 && random.Next(2) == 0)) {
+          IFunctionTree tmp = tree0; tree0 = tree1; tree1 = tmp;
+          int tmpHeight = tree0Height; tree0Height = tree1Height; tree1Height = tmpHeight;
+          int tmpSize = tree0Size; tree0Size = tree1Size; tree1Size = tmpSize;
+        }
+
+        // select a random suboperator of the 'receiving' tree
+        IFunctionTree crossoverPoint = gardener.GetRandomParentNode(tree0);
+        int removedBranchIndex;
+        IFunctionTree removedBranch;
+        IList<IFunction> allowedFunctions;
+        if(crossoverPoint == null) {
+          removedBranchIndex = 0;
+          removedBranch = tree0;
+          allowedFunctions = gardener.GetAllowedSubFunctions(null, 0);
+        } else {
+          removedBranchIndex = random.Next(crossoverPoint.SubTrees.Count);
+          removedBranch = crossoverPoint.SubTrees[removedBranchIndex];
+          allowedFunctions = gardener.GetAllowedSubFunctions(crossoverPoint.Function, removedBranchIndex);
+        }
+        int removedBranchSize = removedBranch.Size;
+        int maxBranchSize = maxTreeSize - (tree0.Size - removedBranchSize);
+        int maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, removedBranch);
+        List<int> removedBranchThread = GetThread(removedBranch, tree0);
+        IFunctionTree insertedBranch = GetReplacementBranch(random, gardener, allowedFunctions, tree1, removedBranchThread, removedBranchSize, maxBranchSize, maxBranchHeight);
+
+        int tries = 0;
+        while(insertedBranch == null) {
+          if(tries++ > MAX_RECOMBINATION_TRIES) {
+            if(random.Next() > 0.5) return tree1;
+            else return tree0;
+          }
+
+          // retry with a different crossoverPoint        
+          crossoverPoint = gardener.GetRandomParentNode(tree0);
+          if(crossoverPoint == null) {
+            removedBranchIndex = 0;
+            removedBranch = tree0;
+            allowedFunctions = gardener.GetAllowedSubFunctions(null, 0);
+          } else {
+            removedBranchIndex = random.Next(crossoverPoint.SubTrees.Count);
+            removedBranch = crossoverPoint.SubTrees[removedBranchIndex];
+            allowedFunctions = gardener.GetAllowedSubFunctions(crossoverPoint.Function, removedBranchIndex);
+          }
+          removedBranchSize = removedBranch.Size;
+          maxBranchSize = maxTreeSize - (tree0.Size - removedBranchSize);
+          maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, removedBranch) + 1;
+          removedBranchThread = GetThread(removedBranch, tree0);
+          insertedBranch = GetReplacementBranch(random, gardener, allowedFunctions, tree1, removedBranchThread, removedBranchSize, maxBranchSize, maxBranchHeight);
+        }
+        if(crossoverPoint != null) {
+          // replace the branch below the crossoverpoint with the selected branch from root1
+          crossoverPoint.RemoveSubTree(removedBranchIndex);
+          crossoverPoint.InsertSubTree(removedBranchIndex, insertedBranch);
+          return tree0;
+        } else {
+          return insertedBranch;
+        }
+      }
+    }
+
+    private IFunctionTree GetReplacementBranch(IRandom random, TreeGardener gardener, IList<IFunction> allowedFunctions, IFunctionTree tree, List<int> removedBranchThread, int removedBranchSize, int maxBranchSize, int maxBranchHeight) {
+      var branches = gardener.GetAllSubTrees(tree).Where(t => allowedFunctions.Contains(t.Function) && t.Size < maxBranchSize && t.Height < maxBranchHeight)
+        .Select(t => new { Tree = t, Size = t.Size, Thread = GetThread(t, tree) }).Where(s => s.Size < 2 * removedBranchSize + 1);
+
+      var shorterBranches = branches.Where(t => t.Size < removedBranchSize);
+      var longerBranches = branches.Where(t => t.Size > removedBranchSize);
+      var equalLengthBranches = branches.Where(t => t.Size == removedBranchSize);
+
+      if(shorterBranches.Count() == 0 || longerBranches.Count() == 0) {
+        if(equalLengthBranches.Count() == 0) {
+          return null;
+        } else {
+          return equalLengthBranches.OrderBy(t => MatchingSteps(removedBranchThread, t.Thread)).Last().Tree;
+        }
+      } else {
+        // invariant: |shorterBranches| > 0  and |longerBranches| > 0
+        double pEqualLength = equalLengthBranches.Count() > 0 ? 1.0 / removedBranchSize : 0.0;
+        double pLonger = (1.0 - pEqualLength) / (longerBranches.Count() * (1.0 + longerBranches.Average(t => t.Size) / shorterBranches.Average(t => t.Size)));
+        double pShorter = (1.0 - pEqualLength - pLonger);
+
+        double r = random.NextDouble();
+        if(r < pLonger) {
+          return longerBranches.OrderBy(t => MatchingSteps(removedBranchThread, t.Thread)).Last().Tree;
+        } else if(r < pLonger + pShorter) {
+          return shorterBranches.OrderBy(t => MatchingSteps(removedBranchThread, t.Thread)).Last().Tree;
+        } else {
+          return equalLengthBranches.OrderBy(t => MatchingSteps(removedBranchThread, t.Thread)).Last().Tree;
+        }
+      }
+    }
+
+    private int MatchingSteps(List<int> removedBranchThread, List<int> list) {
+      int n = Math.Min(removedBranchThread.Count, list.Count);
+      for(int i = 0; i < n; i++) if(removedBranchThread[i] != list[i]) return i;
+      return n;
+    }
+
+    private List<int> GetThread(IFunctionTree t, IFunctionTree tree) {
+      List<int> thread = new List<int>();
+      for(int i = 0; i < tree.SubTrees.Count; i++) {
+        if(t == tree.SubTrees[i]) {
+          thread.Add(i);
+          return thread;
+        } else {
+          thread.AddRange(GetThread(t, tree.SubTrees[i]));
+          if(thread.Count > 0) {
+            thread.Insert(0, i);
+            return thread;
+          }
+        }
+      }
+      return thread;
+    }
+
+
+    // take f and g and create a tree that has f and g as sub-trees 
+    // example
+    //       O
+    //      /|\
+    //     g 2 f 
+    //
+    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      newBranches = new List<IFunctionTree>();
+      // determine the set of possible parent functions
+      ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function });
+      if(possibleParents.Count == 0) throw new InvalidProgramException();
+      // and select a random one
+      IFunctionTree parent = possibleParents.ElementAt(random.Next(possibleParents.Count())).GetTreeNode();
+
+      int nSlots = Math.Max(2, parent.Function.MinArity);
+      // determine which slot can take which sub-trees
+      List<IFunctionTree>[] slots = new List<IFunctionTree>[nSlots];
+      for(int slot = 0; slot < nSlots; slot++) {
+        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+        List<IFunctionTree> allowedTrees = new List<IFunctionTree>();
+        if(allowedSubFunctions.Contains(f.Function)) allowedTrees.Add(f);
+        if(allowedSubFunctions.Contains(g.Function)) allowedTrees.Add(g);
+        slots[slot] = allowedTrees;
+      }
+      // fill the slots in the order of degrees of freedom
+      int[] slotSequence = Enumerable.Range(0, slots.Count()).OrderBy(slot => slots[slot].Count()).ToArray();
+
+      // tmp arry to store the tree for each sub-tree slot of the parent
+      IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots];
+
+      // fill the sub-tree slots of the parent starting with the slots that can take potentially both functions (f and g)
+      for(int i = 0; i < slotSequence.Length; i++) {
+        int slot = slotSequence[i];
+        List<IFunctionTree> allowedTrees = slots[slot];
+        // when neither f nor g fit into the slot => create a new random tree
+        if(allowedTrees.Count() == 0) {
+          var allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+          selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1);
+          newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot]));
+        } else {
+          // select randomly which tree to insert into this slot
+          IFunctionTree selectedTree = allowedTrees[random.Next(allowedTrees.Count())];
+          selectedFunctionTrees[slot] = selectedTree;
+          // remove the tree that we used in this slot from following function-sets
+          for(int j = i + 1; j < slotSequence.Length; j++) {
+            int otherSlot = slotSequence[j];
+            slots[otherSlot].Remove(selectedTree);
+          }
+        }
+      }
+      // actually append the sub-trees to the parent tree
+      for(int i = 0; i < selectedFunctionTrees.Length; i++) {
+        parent.InsertSubTree(i, selectedFunctionTrees[i]);
+      }
+
+      return parent;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Recombination/OnePointCrossOver.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Recombination/OnePointCrossOver.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Recombination/OnePointCrossOver.cs	(revision 656)
@@ -0,0 +1,155 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  /// <summary>
+  /// Implementation of a homologous one point crossover operator as described in: 
+  /// W. B. Langdon and R. Poli.  Foundations of Genetic Programming. Springer-Verlag, 2002.
+  /// </summary>
+  public class OnePointCrossOver : OperatorBase {
+    public override string Description {
+      get {
+        return @"";
+      }
+    }
+    public OnePointCrossOver()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      if((scope.SubScopes.Count % 2) != 0)
+        throw new InvalidOperationException("Number of parents is not even");
+
+      CompositeOperation initOperations = new CompositeOperation();
+
+      int children = scope.SubScopes.Count / 2;
+      for(int i = 0; i < children; i++) {
+        IScope parent1 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent1);
+        IScope parent2 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent2);
+        IScope child = new Scope(i.ToString());
+        IOperation childInitOperation = Cross(gardener, maxTreeSize, maxTreeHeight, scope, random, parent1, parent2, child);
+        initOperations.AddOperation(childInitOperation);
+        scope.AddSubScope(child);
+      }
+
+      return initOperations;
+    }
+
+    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
+      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
+      IFunctionTree newTree = Cross(gardener, parent1, parent2,
+        random, maxTreeSize, maxTreeHeight);
+
+      int newTreeSize = newTree.Size;
+      int newTreeHeight = newTree.Height;
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight)));
+
+      // check if the new tree is valid and if the height of is still in the allowed bounds (we are not so strict for the max-size)
+      Debug.Assert(gardener.IsValidTree(newTree) && newTreeHeight <= maxTreeHeight && newTreeSize <= maxTreeSize);
+      return null;
+    }
+
+
+    private IFunctionTree Cross(TreeGardener gardener, IScope f, IScope g, MersenneTwister random, int maxTreeSize, int maxTreeHeight) {
+      IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      if(tree0Size == 1 && tree1Size == 1) {
+        return CombineTerminals(gardener, tree0, tree1, random);
+      } else {
+        // we are going to insert tree1 into tree0 at a random place so we have to make sure that tree0 is not a terminal
+        // in case both trees are higher than 1 we swap the trees with probability 50%
+        if(tree0Height == 1 || (tree1Height > 1 && random.Next(2) == 0)) {
+          IFunctionTree tmp = tree0; tree0 = tree1; tree1 = tmp;
+          int tmpHeight = tree0Height; tree0Height = tree1Height; tree1Height = tmpHeight;
+          int tmpSize = tree0Size; tree0Size = tree1Size; tree1Size = tmpSize;
+        }
+
+        List<IFunctionTree[]> allowedCrossOverPoints = GetCrossOverPoints(null, tree0, tree1);
+        if(allowedCrossOverPoints.Count == 0) {
+          if(random.NextDouble() < 0.5) return tree0; else return tree1;
+        }
+        IFunctionTree[] crossOverPoints = allowedCrossOverPoints[random.Next(allowedCrossOverPoints.Count)];
+        IFunctionTree parent = crossOverPoints[0];
+        IFunctionTree replacedBranch = crossOverPoints[1];
+        IFunctionTree insertedBranch = crossOverPoints[2];
+        if(parent == null) return insertedBranch;
+        else {
+          int i = 0;
+          while(parent.SubTrees[i] != replacedBranch) i++;
+          parent.RemoveSubTree(i);
+          parent.InsertSubTree(i, insertedBranch);
+          return tree0;
+        }
+      }
+    }
+
+    private List<IFunctionTree[]> GetCrossOverPoints(IFunctionTree parent, IFunctionTree tree0, IFunctionTree tree1) {
+      List<IFunctionTree[]> results = new List<IFunctionTree[]>();
+      if(tree0.Function != tree1.Function) return results;
+
+      int maxArity = Math.Min(tree0.SubTrees.Count, tree1.SubTrees.Count);
+      for(int i = 0; i < maxArity; i++) {
+        results.AddRange(GetCrossOverPoints(tree0, tree0.SubTrees[i], tree1.SubTrees[i]));
+      }
+      if(results.Count == 0) results.Add(new IFunctionTree[] { parent, tree0, tree1 });
+      return results;
+    }
+
+    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random) {
+      if(random.NextDouble() < 0.5) return f; else return g;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Recombination/SizeFairCrossOver.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Recombination/SizeFairCrossOver.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Recombination/SizeFairCrossOver.cs	(revision 656)
@@ -0,0 +1,270 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  /// <summary>
+  /// Implementation of a size fair crossover operator as described in: 
+  /// William B. Langdon 
+  /// Size Fair and Homologous Tree Genetic Programming Crossovers, 
+  /// Genetic Programming and Evolvable Machines, Vol. 1, Number 1/2, pp. 95-119, April 2000
+  /// </summary>
+  public class SizeFairCrossOver : OperatorBase {
+    private const int MAX_RECOMBINATION_TRIES = 20;
+    public override string Description {
+      get {
+        return @"";
+      }
+    }
+    public SizeFairCrossOver()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      if((scope.SubScopes.Count % 2) != 0)
+        throw new InvalidOperationException("Number of parents is not even");
+
+      CompositeOperation initOperations = new CompositeOperation();
+
+      int children = scope.SubScopes.Count / 2;
+      for(int i = 0; i < children; i++) {
+        IScope parent1 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent1);
+        IScope parent2 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent2);
+        IScope child = new Scope(i.ToString());
+        IOperation childInitOperation = Cross(gardener, maxTreeSize, maxTreeHeight, scope, random, parent1, parent2, child);
+        initOperations.AddOperation(childInitOperation);
+        scope.AddSubScope(child);
+      }
+
+      return initOperations;
+    }
+
+    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
+      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
+      List<IFunctionTree> newBranches;
+      IFunctionTree newTree = Cross(gardener, parent1, parent2,
+        random, maxTreeSize, maxTreeHeight, out newBranches);
+
+
+      int newTreeSize = newTree.Size;
+      int newTreeHeight = newTree.Height;
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight)));
+
+      // check if the new tree is valid and if the height of is still in the allowed bounds (we are not so strict for the max-size)
+      Debug.Assert(gardener.IsValidTree(newTree) && newTreeHeight <= maxTreeHeight && newTreeSize <= maxTreeSize);
+      return gardener.CreateInitializationOperation(newBranches, child);
+    }
+
+
+    private IFunctionTree Cross(TreeGardener gardener, IScope f, IScope g, MersenneTwister random, int maxTreeSize, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      if(tree0Size == 1 && tree1Size == 1) {
+        return CombineTerminals(gardener, tree0, tree1, random, maxTreeHeight, out newBranches);
+      } else {
+        newBranches = new List<IFunctionTree>();
+
+        // we are going to insert tree1 into tree0 at a random place so we have to make sure that tree0 is not a terminal
+        // in case both trees are higher than 1 we swap the trees with probability 50%
+        if(tree0Height == 1 || (tree1Height > 1 && random.Next(2) == 0)) {
+          IFunctionTree tmp = tree0; tree0 = tree1; tree1 = tmp;
+          int tmpHeight = tree0Height; tree0Height = tree1Height; tree1Height = tmpHeight;
+          int tmpSize = tree0Size; tree0Size = tree1Size; tree1Size = tmpSize;
+        }
+
+        // select a random suboperator of the 'receiving' tree
+        IFunctionTree crossoverPoint = gardener.GetRandomParentNode(tree0);
+        int removedBranchIndex;
+        IFunctionTree removedBranch;
+        IList<IFunction> allowedFunctions;
+        if(crossoverPoint == null) {
+          removedBranchIndex = 0;
+          removedBranch = tree0;
+          allowedFunctions = gardener.GetAllowedSubFunctions(null, 0);
+        } else {
+          removedBranchIndex = random.Next(crossoverPoint.SubTrees.Count);
+          removedBranch = crossoverPoint.SubTrees[removedBranchIndex];
+          allowedFunctions = gardener.GetAllowedSubFunctions(crossoverPoint.Function, removedBranchIndex);
+        }
+        int removedBranchSize = removedBranch.Size;
+        int maxBranchSize = maxTreeSize - (tree0.Size - removedBranchSize);
+        int maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, removedBranch);
+        IFunctionTree insertedBranch = GetReplacementBranch(random, gardener, allowedFunctions, tree1, removedBranchSize, maxBranchSize, maxBranchHeight);
+
+        int tries = 0;
+        while(insertedBranch == null) {
+          if(tries++ > MAX_RECOMBINATION_TRIES) {
+            if(random.Next() > 0.5) return tree1;
+            else return tree0;
+          }
+
+          // retry with a different crossoverPoint        
+          crossoverPoint = gardener.GetRandomParentNode(tree0);
+          if(crossoverPoint == null) {
+            removedBranchIndex = 0;
+            removedBranch = tree0;
+            allowedFunctions = gardener.GetAllowedSubFunctions(null, 0);
+          } else {
+            removedBranchIndex = random.Next(crossoverPoint.SubTrees.Count);
+            removedBranch = crossoverPoint.SubTrees[removedBranchIndex];
+            allowedFunctions = gardener.GetAllowedSubFunctions(crossoverPoint.Function, removedBranchIndex);
+          }
+          removedBranchSize = removedBranch.Size;
+          maxBranchSize = maxTreeSize - (tree0.Size - removedBranchSize);
+          maxBranchHeight = maxTreeHeight - gardener.GetBranchLevel(tree0, removedBranch) + 1;
+          insertedBranch = GetReplacementBranch(random, gardener, allowedFunctions, tree1, removedBranchSize, maxBranchSize, maxBranchHeight);
+        }
+        if(crossoverPoint != null) {
+          // replace the branch below the crossoverpoint with the selected branch from root1
+          crossoverPoint.RemoveSubTree(removedBranchIndex);
+          crossoverPoint.InsertSubTree(removedBranchIndex, insertedBranch);
+          return tree0;
+        } else {
+          return insertedBranch;
+        }
+      }
+    }
+
+    private IFunctionTree GetReplacementBranch(IRandom random, TreeGardener gardener, IList<IFunction> allowedFunctions, IFunctionTree tree, int removedBranchSize, int maxBranchSize, int maxBranchHeight) {
+      var branches = gardener.GetAllSubTrees(tree).Where(t => allowedFunctions.Contains(t.Function) && t.Size < maxBranchSize && t.Height < maxBranchHeight)
+        .Select(t => new { Tree = t, Size = t.Size }).Where(s => s.Size < 2 * removedBranchSize + 1);
+
+      var shorterBranches = branches.Where(t => t.Size < removedBranchSize);
+      var longerBranches = branches.Where(t => t.Size > removedBranchSize);
+      var equalLengthBranches = branches.Where(t => t.Size == removedBranchSize);
+
+      if(shorterBranches.Count() == 0 || longerBranches.Count() == 0) {
+        if(equalLengthBranches.Count() == 0) {
+          return null;
+        } else {
+          return equalLengthBranches.ElementAt(random.Next(equalLengthBranches.Count())).Tree;
+        }
+      } else {
+        // invariant: |shorterBranches| > 0  and |longerBranches| > 0
+        double pEqualLength = equalLengthBranches.Count() > 0 ? 1.0 / removedBranchSize : 0.0;
+        double pLonger = (1.0 - pEqualLength) / (longerBranches.Count() * (1.0 + longerBranches.Average(t => t.Size) / shorterBranches.Average(t => t.Size)));
+        double pShorter = (1.0 - pEqualLength - pLonger);
+
+        double r = random.NextDouble();
+        if(r < pLonger) {
+          return longerBranches.ElementAt(random.Next(longerBranches.Count())).Tree;
+        } else if(r < pLonger + pShorter) {
+          return shorterBranches.ElementAt(random.Next(shorterBranches.Count())).Tree;
+        } else {
+          return equalLengthBranches.ElementAt(random.Next(equalLengthBranches.Count())).Tree;
+        }
+      }
+    }
+
+
+    // take f and g and create a tree that has f and g as sub-trees 
+    // example
+    //       O
+    //      /|\
+    //     g 2 f 
+    //
+    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      newBranches = new List<IFunctionTree>();
+      // determine the set of possible parent functions
+      ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function });
+      if(possibleParents.Count == 0) throw new InvalidProgramException();
+      // and select a random one
+      IFunctionTree parent = possibleParents.ElementAt(random.Next(possibleParents.Count())).GetTreeNode();
+
+      int nSlots = Math.Max(2, parent.Function.MinArity);
+      // determine which slot can take which sub-trees
+      List<IFunctionTree>[] slots = new List<IFunctionTree>[nSlots];
+      for(int slot = 0; slot < nSlots; slot++) {
+        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+        List<IFunctionTree> allowedTrees = new List<IFunctionTree>();
+        if(allowedSubFunctions.Contains(f.Function)) allowedTrees.Add(f);
+        if(allowedSubFunctions.Contains(g.Function)) allowedTrees.Add(g);
+        slots[slot] = allowedTrees;
+      }
+      // fill the slots in the order of degrees of freedom
+      int[] slotSequence = Enumerable.Range(0, slots.Count()).OrderBy(slot => slots[slot].Count()).ToArray();
+
+      // tmp arry to store the tree for each sub-tree slot of the parent
+      IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots];
+
+      // fill the sub-tree slots of the parent starting with the slots that can take potentially both functions (f and g)
+      for(int i = 0; i < slotSequence.Length; i++) {
+        int slot = slotSequence[i];
+        List<IFunctionTree> allowedTrees = slots[slot];
+        // when neither f nor g fit into the slot => create a new random tree
+        if(allowedTrees.Count() == 0) {
+          var allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+          selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1);
+          newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot]));
+        } else {
+          // select randomly which tree to insert into this slot
+          IFunctionTree selectedTree = allowedTrees[random.Next(allowedTrees.Count())];
+          selectedFunctionTrees[slot] = selectedTree;
+          // remove the tree that we used in this slot from following function-sets
+          for(int j = i + 1; j < slotSequence.Length; j++) {
+            int otherSlot = slotSequence[j];
+            slots[otherSlot].Remove(selectedTree);
+          }
+        }
+      }
+      // actually append the sub-trees to the parent tree
+      for(int i = 0; i < selectedFunctionTrees.Length; i++) {
+        parent.InsertSubTree(i, selectedFunctionTrees[i]);
+      }
+
+      return parent;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/Recombination/StandardCrossOver.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/Recombination/StandardCrossOver.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/Recombination/StandardCrossOver.cs	(revision 656)
@@ -0,0 +1,259 @@
+#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.Core;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+
+namespace HeuristicLab.GP {
+  public class StandardCrossOver : OperatorBase {
+    private const int MAX_RECOMBINATION_TRIES = 20;
+    public override string Description {
+      get {
+        return @"Takes two parent individuals P0 and P1 each. Selects a random node N0 of P0 and a random node N1 of P1.
+And replaces the branch with root0 N0 in P0 with N1 from P1 if the tree-size limits are not violated.
+When recombination with N0 and N1 would create a tree that is too large or invalid the operator randomly selects new N0 and N1 
+until a valid configuration is found.";
+      }
+    }
+    public StandardCrossOver()
+      : base() {
+      AddVariableInfo(new VariableInfo("Random", "Pseudo random number generator", typeof(MersenneTwister), VariableKind.In));
+      AddVariableInfo(new VariableInfo("OperatorLibrary", "The operator library containing all available operators", typeof(GPOperatorLibrary), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeHeight", "The maximal allowed height of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("MaxTreeSize", "The maximal allowed size (number of nodes) of the tree", typeof(IntData), VariableKind.In));
+      AddVariableInfo(new VariableInfo("FunctionTree", "The tree to mutate", typeof(IFunctionTree), VariableKind.In | VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeSize", "The size (number of nodes) of the tree", typeof(IntData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TreeHeight", "The height of the tree", typeof(IntData), VariableKind.New));
+    }
+
+    public override IOperation Apply(IScope scope) {
+      MersenneTwister random = GetVariableValue<MersenneTwister>("Random", scope, true);
+      GPOperatorLibrary opLibrary = GetVariableValue<GPOperatorLibrary>("OperatorLibrary", scope, true);
+      int maxTreeHeight = GetVariableValue<IntData>("MaxTreeHeight", scope, true).Data;
+      int maxTreeSize = GetVariableValue<IntData>("MaxTreeSize", scope, true).Data;
+
+      TreeGardener gardener = new TreeGardener(random, opLibrary);
+
+      if((scope.SubScopes.Count % 2) != 0)
+        throw new InvalidOperationException("Number of parents is not even");
+
+      CompositeOperation initOperations = new CompositeOperation();
+
+      int children = scope.SubScopes.Count / 2;
+      for(int i = 0; i < children; i++) {
+        IScope parent1 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent1);
+        IScope parent2 = scope.SubScopes[0];
+        scope.RemoveSubScope(parent2);
+        IScope child = new Scope(i.ToString());
+        IOperation childInitOperation = Cross(gardener, maxTreeSize, maxTreeHeight, scope, random, parent1, parent2, child);
+        initOperations.AddOperation(childInitOperation);
+        scope.AddSubScope(child);
+      }
+
+      return initOperations;
+    }
+
+    private IOperation Cross(TreeGardener gardener, int maxTreeSize, int maxTreeHeight,
+      IScope scope, MersenneTwister random, IScope parent1, IScope parent2, IScope child) {
+      List<IFunctionTree> newBranches;
+      IFunctionTree newTree = Cross(gardener, parent1, parent2,
+        random, maxTreeSize, maxTreeHeight, out newBranches);
+
+
+      int newTreeSize = newTree.Size;
+      int newTreeHeight = newTree.Height;
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("FunctionTree"), newTree));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeSize"), new IntData(newTreeSize)));
+      child.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TreeHeight"), new IntData(newTreeHeight)));
+
+      // check if the new tree is valid and if the height of is still in the allowed bounds (we are not so strict for the max-size)
+      Debug.Assert(gardener.IsValidTree(newTree) && newTreeHeight <= maxTreeHeight && newTreeSize <= maxTreeSize);
+      return gardener.CreateInitializationOperation(newBranches, child);
+    }
+
+
+    private IFunctionTree Cross(TreeGardener gardener, IScope f, IScope g, MersenneTwister random, int maxTreeSize, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      IFunctionTree tree0 = f.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree0Height = f.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree0Size = f.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      IFunctionTree tree1 = g.GetVariableValue<IFunctionTree>("FunctionTree", false);
+      int tree1Height = g.GetVariableValue<IntData>("TreeHeight", false).Data;
+      int tree1Size = g.GetVariableValue<IntData>("TreeSize", false).Data;
+
+      if(tree0Size == 1 && tree1Size == 1) {
+        return CombineTerminals(gardener, tree0, tree1, random, maxTreeHeight, out newBranches);
+      } else {
+        newBranches = new List<IFunctionTree>();
+
+        // we are going to insert tree1 into tree0 at a random place so we have to make sure that tree0 is not a terminal
+        // in case both trees are higher than 1 we swap the trees with probability 50%
+        if(tree0Height == 1 || (tree1Height > 1 && random.Next(2) == 0)) {
+          IFunctionTree tmp = tree0; tree0 = tree1; tree1 = tmp;
+          int tmpHeight = tree0Height; tree0Height = tree1Height; tree1Height = tmpHeight;
+          int tmpSize = tree0Size; tree0Size = tree1Size; tree1Size = tmpSize;
+        }
+
+        // save the roots because later on we change tree0 and tree1 while searching a valid tree configuration
+        IFunctionTree root0 = tree0;
+        IFunctionTree root1 = tree1;
+        int root0Height = tree0Height;
+        int root1Height = tree1Height;
+        int rootSize = tree0Size;
+
+        // select a random suboperators of the two trees at a random level
+        int tree0Level = random.Next(root0Height - 1); // since we checked before that the height of tree0 is > 1 this is OK
+        int tree1Level = random.Next(root1Height);
+        tree0 = gardener.GetRandomBranch(tree0, tree0Level);
+        tree1 = gardener.GetRandomBranch(tree1, tree1Level);
+
+        // recalculate the size and height of tree1 (the one that we want to insert) because we need to check constraints later on
+        tree1Size = tree1.Size;
+        tree1Height = tree1.Height;
+
+        List<int> possibleChildIndices = new List<int>();
+
+        // Now tree0 is supposed to take tree1 as one if its children. If this is not possible,
+        // then go down in either of the two trees as far as possible. If even then it is not possible
+        // to merge the trees then throw an exception
+        // find the list of allowed indices (regarding allowed sub-trees, maxTreeSize and maxTreeHeight)
+        for(int i = 0; i < tree0.SubTrees.Count; i++) {
+          int subTreeSize = tree0.SubTrees[i].Size;
+
+          // the index is ok when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
+          if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) &&
+            rootSize - subTreeSize + tree1Size < maxTreeSize &&
+            tree0Level + tree1Height < maxTreeHeight) {
+            possibleChildIndices.Add(i);
+          }
+        }
+        int tries = 0;
+        while(possibleChildIndices.Count == 0) {
+          if(tries++ > MAX_RECOMBINATION_TRIES) {
+            if(random.Next() > 0.5) return root1;
+            else return root0;
+          }
+          // we couln't find a possible configuration given the current tree0 and tree1
+          // possible reasons for this are: 
+          //  - tree1 is not allowed as sub-tree of tree0
+          //  - appending tree1 as child of tree0 would create a tree that exceedes the maxTreeHeight
+          //  - replacing any child of tree0 with tree1 woulde create a tree that exceedes the maxTeeSize
+          // thus we just try until we find a valid configuration
+
+          tree0Level = random.Next(root0Height - 1);
+          tree1Level = random.Next(root1Height);
+          tree0 = gardener.GetRandomBranch(root0, tree0Level);
+          tree1 = gardener.GetRandomBranch(root1, tree1Level);
+
+          // recalculate the size and height of tree1 (the one that we want to insert) because we need to check constraints later on
+          tree1Size = tree1.Size;
+          tree1Height = tree1.Height;
+          // recalculate the list of possible indices 
+          possibleChildIndices.Clear();
+          for(int i = 0; i < tree0.SubTrees.Count; i++) {
+            int subTreeSize = tree0.SubTrees[i].Size;
+
+            // when the function is allowed as sub-tree and we don't violate the maxSize and maxHeight constraints
+            // the index is ok
+            if(gardener.GetAllowedSubFunctions(tree0.Function, i).Contains(tree1.Function) &&
+              rootSize - subTreeSize + tree1Size < maxTreeSize &&
+              tree0Level + tree1Height < maxTreeHeight) {
+              possibleChildIndices.Add(i);
+            }
+          }
+        }
+        // replace the existing sub-tree at a random index in tree0 with tree1
+        int selectedIndex = possibleChildIndices[random.Next(possibleChildIndices.Count)];
+        tree0.RemoveSubTree(selectedIndex);
+        tree0.InsertSubTree(selectedIndex, tree1);
+        return root0;
+      }
+    }
+
+
+    // take f and g and create a tree that has f and g as sub-trees 
+    // example
+    //       O
+    //      /|\
+    //     g 2 f 
+    //
+    private IFunctionTree CombineTerminals(TreeGardener gardener, IFunctionTree f, IFunctionTree g, MersenneTwister random, int maxTreeHeight, out List<IFunctionTree> newBranches) {
+      newBranches = new List<IFunctionTree>();
+      // determine the set of possible parent functions
+      ICollection<IFunction> possibleParents = gardener.GetPossibleParents(new List<IFunction>() { f.Function, g.Function });
+      if(possibleParents.Count == 0) throw new InvalidProgramException();
+      // and select a random one
+      IFunctionTree parent = possibleParents.ElementAt(random.Next(possibleParents.Count())).GetTreeNode();
+
+      int nSlots = Math.Max(2, parent.Function.MinArity);
+      // determine which slot can take which sub-trees
+      List<IFunctionTree>[] slots = new List<IFunctionTree>[nSlots];
+      for(int slot = 0; slot < nSlots; slot++) {
+        ICollection<IFunction> allowedSubFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+        List<IFunctionTree> allowedTrees = new List<IFunctionTree>();
+        if(allowedSubFunctions.Contains(f.Function)) allowedTrees.Add(f);
+        if(allowedSubFunctions.Contains(g.Function)) allowedTrees.Add(g);
+        slots[slot] = allowedTrees;
+      }
+      // fill the slots in the order of degrees of freedom
+      int[] slotSequence = Enumerable.Range(0, slots.Count()).OrderBy(slot => slots[slot].Count()).ToArray();
+
+      // tmp arry to store the tree for each sub-tree slot of the parent
+      IFunctionTree[] selectedFunctionTrees = new IFunctionTree[nSlots];
+
+      // fill the sub-tree slots of the parent starting with the slots that can take potentially both functions (f and g)
+      for(int i = 0; i < slotSequence.Length; i++) {
+        int slot = slotSequence[i];
+        List<IFunctionTree> allowedTrees = slots[slot];
+        // when neither f nor g fit into the slot => create a new random tree
+        if(allowedTrees.Count() == 0) {
+          var allowedFunctions = gardener.GetAllowedSubFunctions(parent.Function, slot);
+          selectedFunctionTrees[slot] = gardener.CreateRandomTree(allowedFunctions, 1, 1);
+          newBranches.AddRange(gardener.GetAllSubTrees(selectedFunctionTrees[slot]));
+        } else {
+          // select randomly which tree to insert into this slot
+          IFunctionTree selectedTree = allowedTrees[random.Next(allowedTrees.Count())];
+          selectedFunctionTrees[slot] = selectedTree;
+          // remove the tree that we used in this slot from following function-sets
+          for(int j = i + 1; j < slotSequence.Length; j++) {
+            int otherSlot = slotSequence[j];
+            slots[otherSlot].Remove(selectedTree);
+          }
+        }
+      }
+      // actually append the sub-trees to the parent tree
+      for(int i = 0; i < selectedFunctionTrees.Length; i++) {
+        parent.InsertSubTree(i, selectedFunctionTrees[i]);
+      }
+
+      return parent;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.GP/TreeGardener.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/TreeGardener.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/TreeGardener.cs	(revision 656)
@@ -0,0 +1,498 @@
+#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.Text;
+using HeuristicLab.Core;
+using HeuristicLab.Constraints;
+using System.Diagnostics;
+using HeuristicLab.Data;
+using System.Linq;
+using HeuristicLab.Random;
+using HeuristicLab.Operators;
+using System.Collections;
+using HeuristicLab.Selection;
+
+namespace HeuristicLab.GP {
+  internal class TreeGardener {
+    private IRandom random;
+    private GPOperatorLibrary funLibrary;
+    private List<IFunction> functions;
+
+    private List<IFunction> terminals;
+    internal IList<IFunction> Terminals {
+      get { return terminals; }
+    }
+
+    private List<IFunction> allFunctions;
+    internal IList<IFunction> AllFunctions {
+      get { return allFunctions; }
+    }
+
+    #region constructors
+    internal TreeGardener(IRandom random, GPOperatorLibrary funLibrary) {
+      this.random = random;
+      this.funLibrary = funLibrary;
+      this.allFunctions = new List<IFunction>();
+      terminals = new List<IFunction>();
+      functions = new List<IFunction>();
+      // init functions and terminals based on constraints
+      foreach(IFunction fun in funLibrary.Group.Operators) {
+        if(fun.MaxArity == 0) {
+          terminals.Add(fun);
+          allFunctions.Add(fun);
+        } else {
+          functions.Add(fun);
+          allFunctions.Add(fun);
+        }
+      }
+    }
+    #endregion
+
+    #region random initialization
+    /// <summary>
+    /// Creates a random balanced tree with a maximal size and height. When the max-height or max-size are 1 it will return a random terminal.
+    /// In other cases it will return either a terminal (tree of size 1) or any other tree with a function in it's root (at least height 2).
+    /// </summary>
+    /// <param name="maxTreeSize">Maximal size of the tree (number of nodes).</param>
+    /// <param name="maxTreeHeight">Maximal height of the tree.</param>
+    /// <returns></returns>
+    internal IFunctionTree CreateBalancedRandomTree(int maxTreeSize, int maxTreeHeight) {
+      IFunction rootFunction = GetRandomRoot(maxTreeSize, maxTreeHeight);
+      IFunctionTree tree = MakeBalancedTree(rootFunction, maxTreeHeight - 1);
+      return tree;
+    }
+
+    /// <summary>
+    /// Creates a random (unbalanced) tree with a maximal size and height. When the max-height or max-size are 1 it will return a random terminal.
+    /// In other cases it will return either a terminal (tree of size 1) or any other tree with a function in it's root (at least height 2).
+    /// </summary>
+    /// <param name="maxTreeSize">Maximal size of the tree (number of nodes).</param>
+    /// <param name="maxTreeHeight">Maximal height of the tree.</param>
+    /// <returns></returns>
+    internal IFunctionTree CreateUnbalancedRandomTree(int maxTreeSize, int maxTreeHeight) {
+      IFunction rootFunction = GetRandomRoot(maxTreeSize, maxTreeHeight);
+      IFunctionTree tree = MakeUnbalancedTree(rootFunction, maxTreeHeight - 1);
+      return tree;
+    }
+
+    internal IFunctionTree PTC2(IRandom random, int size, int maxDepth) {
+      return PTC2(random, GetRandomRoot(size, maxDepth), size, maxDepth);
+    }
+
+    internal IFunctionTree PTC2(IRandom random, IFunction rootF, int size, int maxDepth) {
+      IFunctionTree root = rootF.GetTreeNode();
+      if(size <= 1 || maxDepth <= 1) return root;
+      List<object[]> list = new List<object[]>();
+      int currentSize = 1;
+      int totalListMinSize = 0;
+      int minArity = root.Function.MinArity;
+      int maxArity = root.Function.MaxArity;
+      if(maxArity >= size) {
+        maxArity = size;
+      }
+      int actualArity = random.Next(minArity, maxArity + 1);
+      totalListMinSize += GetMinimalTreeSize(root.Function) - 1;
+      for(int i = 0; i < actualArity; i++) {
+        // insert a dummy sub-tree and add the pending extension to the list
+        root.AddSubTree(null);
+        list.Add(new object[] { root, i, 2 });
+      }
+
+      while(list.Count > 0 && totalListMinSize + currentSize < size) {
+        int randomIndex = random.Next(list.Count);
+        object[] nextExtension = list[randomIndex];
+        list.RemoveAt(randomIndex);
+        IFunctionTree parent = (IFunctionTree)nextExtension[0];
+        int a = (int)nextExtension[1];
+        int d = (int)nextExtension[2];
+        if(d == maxDepth) {
+          parent.RemoveSubTree(a);
+          IFunctionTree branch = CreateRandomTree(GetAllowedSubFunctions(parent.Function, a), 1, 1);
+          parent.InsertSubTree(a, branch); // insert a smallest possible tree
+          currentSize += branch.Size;
+          totalListMinSize -= branch.Size;
+        } else {
+          IFunction selectedFunction = RandomSelect(GetAllowedSubFunctions(parent.Function, a).Where(
+            f => !IsTerminal(f) && GetMinimalTreeHeight(f) + (d - 1) <= maxDepth).ToArray());
+          IFunctionTree newTree = selectedFunction.GetTreeNode();
+          parent.RemoveSubTree(a);
+          parent.InsertSubTree(a, newTree);
+          currentSize++;
+          totalListMinSize--;
+
+          minArity = selectedFunction.MinArity;
+          maxArity = selectedFunction.MaxArity;
+          if(maxArity >= size) {
+            maxArity = size;
+          }
+          actualArity = random.Next(minArity, maxArity + 1);
+          for(int i = 0; i < actualArity; i++) {
+            // insert a dummy sub-tree and add the pending extension to the list
+            newTree.AddSubTree(null);
+            list.Add(new object[] { newTree, i, d + 1 });
+          }
+          totalListMinSize += GetMinimalTreeSize(newTree.Function) - 1;
+        }
+      }
+      while(list.Count > 0) {
+        int randomIndex = random.Next(list.Count);
+        object[] nextExtension = list[randomIndex];
+        list.RemoveAt(randomIndex);
+        IFunctionTree parent = (IFunctionTree)nextExtension[0];
+        int a = (int)nextExtension[1];
+        int d = (int)nextExtension[2];
+        parent.RemoveSubTree(a);
+        parent.InsertSubTree(a,
+          CreateRandomTree(GetAllowedSubFunctions(parent.Function, a), 1, 1)); // append a tree with minimal possible height
+      }
+      return root;
+    }
+
+    /// <summary>
+    /// selects a random function from allowedFunctions and creates a random (unbalanced) tree with maximal size and height.
+    /// </summary>
+    /// <param name="allowedFunctions">Set of allowed functions.</param>
+    /// <param name="maxTreeSize">Maximal size of the tree (number of nodes).</param>
+    /// <param name="maxTreeHeight">Maximal height of the tree.</param>
+    /// <returns>New random unbalanced tree</returns>
+    internal IFunctionTree CreateRandomTree(ICollection<IFunction> allowedFunctions, int maxTreeSize, int maxTreeHeight) {
+      // get the minimal needed height based on allowed functions and extend the max-height if necessary
+      int minTreeHeight = allowedFunctions.Select(f => GetMinimalTreeHeight(f)).Min();
+      if(minTreeHeight > maxTreeHeight)
+        maxTreeHeight = minTreeHeight;
+      // get the minimal needed size based on allowed functions and extend the max-size if necessary
+      int minTreeSize = allowedFunctions.Select(f => GetMinimalTreeSize(f)).Min();
+      if(minTreeSize > maxTreeSize)
+        maxTreeSize = minTreeSize;
+
+      // select a random value for the size and height
+      int treeHeight = random.Next(minTreeHeight, maxTreeHeight + 1);
+      int treeSize = random.Next(minTreeSize, maxTreeSize + 1);
+
+      // filter the set of allowed functions and select only from those that fit into the given maximal size and height limits
+      IFunction[] possibleFunctions = allowedFunctions.Where(f => GetMinimalTreeHeight(f) <= treeHeight &&
+        GetMinimalTreeSize(f) <= treeSize).ToArray();
+      IFunction selectedFunction = RandomSelect(possibleFunctions);
+
+      // build the tree 
+      IFunctionTree root;
+      root = PTC2(random, selectedFunction, maxTreeSize, maxTreeHeight);
+      return root;
+    }
+
+    internal CompositeOperation CreateInitializationOperation(ICollection<IFunctionTree> trees, IScope scope) {
+      // needed for the parameter shaking operation
+      CompositeOperation initializationOperation = new CompositeOperation();
+      Scope tempScope = new Scope("Temp. initialization scope");
+
+      var parametricTrees = trees.Where(t => t.Function.GetVariable(FunctionBase.INITIALIZATION) != null);
+      foreach(IFunctionTree tree in parametricTrees) {
+        // enqueue an initialization operation for each operator with local variables 
+        IOperator initialization = (IOperator)tree.Function.GetVariable(FunctionBase.INITIALIZATION).Value;
+        Scope initScope = new Scope();
+        // copy the local variables into a temporary scope used for initialization
+        foreach(IVariable variable in tree.LocalVariables) {
+          initScope.AddVariable(variable);
+        }
+        tempScope.AddSubScope(initScope);
+        initializationOperation.AddOperation(new AtomicOperation(initialization, initScope));
+      }
+      Scope backupScope = new Scope("backup");
+      foreach(Scope subScope in scope.SubScopes) {
+        backupScope.AddSubScope(subScope);
+      }
+      scope.AddSubScope(tempScope);
+      scope.AddSubScope(backupScope);
+      // add an operation to remove the temporary scopes        
+      initializationOperation.AddOperation(new AtomicOperation(new RightReducer(), scope));
+      return initializationOperation;
+    }
+    #endregion
+
+    #region tree information gathering
+    internal IFunctionTree GetRandomParentNode(IFunctionTree tree) {
+      List<IFunctionTree> parentNodes = new List<IFunctionTree>();
+
+      // add null for the parent of the root node
+      parentNodes.Add(null);
+
+      TreeForEach(tree, delegate(IFunctionTree possibleParentNode) {
+        if(possibleParentNode.SubTrees.Count > 0) {
+          parentNodes.Add(possibleParentNode);
+        }
+      });
+
+      return parentNodes[random.Next(parentNodes.Count)];
+    }
+
+    internal ICollection<IFunctionTree> GetAllSubTrees(IFunctionTree root) {
+      List<IFunctionTree> allTrees = new List<IFunctionTree>();
+      TreeForEach(root, t => { allTrees.Add(t); });
+      return allTrees;
+    }
+
+    /// <summary>
+    /// returns the height level of branch in the tree
+    /// if the branch == tree => 1
+    /// if branch is in the sub-trees of tree => 2
+    /// ...
+    /// if branch is not found => -1
+    /// </summary>
+    /// <param name="tree">root of the function tree to process</param>
+    /// <param name="branch">branch that is searched in the tree</param>
+    /// <returns></returns>
+    internal int GetBranchLevel(IFunctionTree tree, IFunctionTree branch) {
+      return GetBranchLevelHelper(tree, branch, 1);
+    }
+
+    // 'tail-recursive' helper
+    private int GetBranchLevelHelper(IFunctionTree tree, IFunctionTree branch, int level) {
+      if(branch == tree) return level;
+
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        int result = GetBranchLevelHelper(subTree, branch, level + 1);
+        if(result != -1) return result;
+      }
+
+      return -1;
+    }
+
+    internal bool IsValidTree(IFunctionTree tree) {
+      for(int i = 0; i < tree.SubTrees.Count; i++) {
+        if(!tree.Function.AllowedSubFunctions(i).Contains(tree.SubTrees[i].Function)) return false;
+      }
+
+      if(tree.SubTrees.Count < tree.Function.MinArity || tree.SubTrees.Count > tree.Function.MaxArity)
+        return false;
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        if(!IsValidTree(subTree)) return false;
+      }
+      return true;
+    }
+
+    // returns a random branch from the specified level in the tree
+    internal IFunctionTree GetRandomBranch(IFunctionTree tree, int level) {
+      if(level == 0) return tree;
+      List<IFunctionTree> branches = new List<IFunctionTree>();
+      GetBranchesAtLevel(tree, level, branches);
+      return branches[random.Next(branches.Count)];
+    }
+    #endregion
+
+    #region function information (arity, allowed childs and parents)
+    internal ICollection<IFunction> GetPossibleParents(List<IFunction> list) {
+      List<IFunction> result = new List<IFunction>();
+      foreach(IFunction f in functions) {
+        if(IsPossibleParent(f, list)) {
+          result.Add(f);
+        }
+      }
+      return result;
+    }
+
+    private bool IsPossibleParent(IFunction f, List<IFunction> children) {
+      int minArity = f.MinArity;
+      int maxArity = f.MaxArity;
+      // note: we can't assume that the operators in the children list have different types!
+
+      // when the maxArity of this function is smaller than the list of operators that
+      // should be included as sub-operators then it can't be a parent
+      if(maxArity < children.Count()) {
+        return false;
+      }
+      int nSlots = Math.Max(minArity, children.Count);
+
+      List<HashSet<IFunction>> slotSets = new List<HashSet<IFunction>>();
+
+      // we iterate through all slots for sub-trees and calculate the set of 
+      // allowed functions for this slot.
+      // we only count those slots that can hold at least one of the children that we should combine
+      for(int slot = 0; slot < nSlots; slot++) {
+        HashSet<IFunction> functionSet = new HashSet<IFunction>(f.AllowedSubFunctions(slot));
+        if(functionSet.Count() > 0) {
+          slotSets.Add(functionSet);
+        }
+      }
+
+      // ok at the end of this operation we know how many slots of the parent can actually
+      // hold one of our children.
+      // if the number of slots is smaller than the number of children we can be sure that
+      // we can never combine all children as sub-trees of the function and thus the function
+      // can't be a parent.
+      if(slotSets.Count() < children.Count()) {
+        return false;
+      }
+
+      // finally we sort the sets by size and beginning from the first set select one
+      // function for the slot and thus remove it as possible sub-tree from the remaining sets.
+      // when we can successfully assign all available children to a slot the function is a valid parent
+      // when only a subset of all children can be assigned to slots the function is no valid parent
+      slotSets.Sort((p, q) => p.Count() - q.Count());
+
+      int assignments = 0;
+      for(int i = 0; i < slotSets.Count() - 1; i++) {
+        if(slotSets[i].Count > 0) {
+          IFunction selected = slotSets[i].ElementAt(0);
+          assignments++;
+          for(int j = i + 1; j < slotSets.Count(); j++) {
+            slotSets[j].Remove(selected);
+          }
+        }
+      }
+
+      // sanity check 
+      if(assignments > children.Count) throw new InvalidProgramException();
+      return assignments == children.Count - 1;
+    }
+    internal IList<IFunction> GetAllowedParents(IFunction child, int childIndex) {
+      List<IFunction> parents = new List<IFunction>();
+      foreach(IFunction function in functions) {
+        ICollection<IFunction> allowedSubFunctions = GetAllowedSubFunctions(function, childIndex);
+        if(allowedSubFunctions.Contains(child)) {
+          parents.Add(function);
+        }
+      }
+      return parents;
+    }
+    internal bool IsTerminal(IFunction f) {
+      return f.MinArity == 0 && f.MaxArity == 0;
+    }
+    internal IList<IFunction> GetAllowedSubFunctions(IFunction f, int index) {
+      if(f == null) {
+        return allFunctions;
+      } else {
+        return f.AllowedSubFunctions(index);
+      }
+    }
+    #endregion
+
+    #region private utility methods
+    private IFunction GetRandomRoot(int maxTreeSize, int maxTreeHeight) {
+      if(maxTreeHeight == 1 || maxTreeSize == 1) {
+        IFunction selectedTerminal = RandomSelect(terminals);
+        return selectedTerminal;
+      } else {
+        IFunction[] possibleFunctions = functions.Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
+          GetMinimalTreeSize(f) <= maxTreeSize).ToArray();
+        IFunction selectedFunction = RandomSelect(possibleFunctions);
+        return selectedFunction;
+      }
+    }
+
+
+    private IFunctionTree MakeUnbalancedTree(IFunction parent, int maxTreeHeight) {
+      if(maxTreeHeight == 0) return parent.GetTreeNode();
+      int minArity = parent.MinArity;
+      int maxArity = parent.MaxArity;
+      int actualArity = random.Next(minArity, maxArity + 1);
+      if(actualArity > 0) {
+        IFunctionTree parentTree = parent.GetTreeNode();
+        for(int i = 0; i < actualArity; i++) {
+          IFunction[] possibleFunctions = GetAllowedSubFunctions(parent, i).Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight).ToArray();
+          IFunction selectedFunction = RandomSelect(possibleFunctions);
+          IFunctionTree newSubTree = MakeUnbalancedTree(selectedFunction, maxTreeHeight - 1);
+          parentTree.InsertSubTree(i, newSubTree);
+        }
+        return parentTree;
+      }
+      return parent.GetTreeNode();
+    }
+
+
+    // NOTE: this method doesn't build fully balanced trees because we have constraints on the
+    // types of possible sub-functions which can indirectly impose a limit for the depth of a given sub-tree
+    private IFunctionTree MakeBalancedTree(IFunction parent, int maxTreeHeight) {
+      if(maxTreeHeight == 0) return parent.GetTreeNode();
+      int minArity = parent.MinArity;
+      int maxArity = parent.MaxArity;
+      int actualArity = random.Next(minArity, maxArity + 1);
+      if(actualArity > 0) {
+        IFunctionTree parentTree = parent.GetTreeNode();
+        for(int i = 0; i < actualArity; i++) {
+          // first try to find a function that fits into the maxHeight limit
+          IFunction[] possibleFunctions = GetAllowedSubFunctions(parent, i).Where(f => GetMinimalTreeHeight(f) <= maxTreeHeight &&
+            !IsTerminal(f)).ToArray();
+          // no possible function found => extend function set to terminals
+          if(possibleFunctions.Length == 0) {
+            possibleFunctions = GetAllowedSubFunctions(parent, i).Where(f => IsTerminal(f)).ToArray();
+            IFunction selectedTerminal = RandomSelect(possibleFunctions);
+            IFunctionTree newTree = selectedTerminal.GetTreeNode();
+            parentTree.InsertSubTree(i, newTree);
+          } else {
+            IFunction selectedFunction = RandomSelect(possibleFunctions);
+            IFunctionTree newTree = MakeBalancedTree(selectedFunction, maxTreeHeight - 1);
+            parentTree.InsertSubTree(i, newTree);
+          }
+        }
+        return parentTree;
+      }
+      return parent.GetTreeNode();
+    }
+
+    private int GetMinimalTreeHeight(IOperator op) {
+      return ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_HEIGHT).Value).Data;
+    }
+
+    private int GetMinimalTreeSize(IOperator op) {
+      return ((IntData)op.GetVariable(GPOperatorLibrary.MIN_TREE_SIZE).Value).Data;
+    }
+
+    private void TreeForEach(IFunctionTree tree, Action<IFunctionTree> action) {
+      action(tree);
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        TreeForEach(subTree, action);
+      }
+    }
+
+    private void GetBranchesAtLevel(IFunctionTree tree, int level, List<IFunctionTree> result) {
+      if(level == 1) result.AddRange(tree.SubTrees);
+      foreach(IFunctionTree subTree in tree.SubTrees) {
+        if(subTree.Height >= level - 1)
+          GetBranchesAtLevel(subTree, level - 1, result);
+      }
+    }
+
+    private IFunction RandomSelect(IList<IFunction> functionSet) {
+      double[] accumulatedTickets = new double[functionSet.Count];
+      double ticketAccumulator = 0;
+      int i = 0;
+      // precalculate the slot-sizes
+      foreach(IFunction function in functionSet) {
+        ticketAccumulator += ((DoubleData)function.GetVariable(GPOperatorLibrary.TICKETS).Value).Data;
+        accumulatedTickets[i] = ticketAccumulator;
+        i++;
+      }
+      // throw ball
+      double r = random.NextDouble() * ticketAccumulator;
+      // find the slot that has been hit
+      for(i = 0; i < accumulatedTickets.Length; i++) {
+        if(r < accumulatedTickets[i]) return functionSet[i];
+      }
+      // sanity check
+      throw new InvalidProgramException(); // should never happen
+    }
+
+    #endregion
+
+  }
+}
Index: trunk/sources/HeuristicLab.GP/UnknownFunctionException.cs
===================================================================
--- trunk/sources/HeuristicLab.GP/UnknownFunctionException.cs	(revision 656)
+++ trunk/sources/HeuristicLab.GP/UnknownFunctionException.cs	(revision 656)
@@ -0,0 +1,33 @@
+#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.Text;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.GP {
+  public class UnknownFunctionException : Exception {
+    public UnknownFunctionException(string functionName)
+      : base("Function "+functionName+" was not expected and can't be handled.") {
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Scheduling.JSSP/HeuristicLab.Scheduling.JSSP.csproj
===================================================================
--- trunk/sources/HeuristicLab.Scheduling.JSSP/HeuristicLab.Scheduling.JSSP.csproj	(revision 642)
+++ trunk/sources/HeuristicLab.Scheduling.JSSP/HeuristicLab.Scheduling.JSSP.csproj	(revision 656)
@@ -3,5 +3,5 @@
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.30729</ProductVersion>
+    <ProductVersion>9.0.21022</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{4C0EF782-CC94-4A94-BC3E-661D2600559B}</ProjectGuid>
@@ -119,8 +119,4 @@
       <Name>HeuristicLab.Data</Name>
     </ProjectReference>
-    <ProjectReference Include="..\HeuristicLab.Functions\HeuristicLab.Functions.csproj">
-      <Project>{B95CA6E2-34BC-4430-994D-BD6E99375319}</Project>
-      <Name>HeuristicLab.Functions</Name>
-    </ProjectReference>
     <ProjectReference Include="..\HeuristicLab.Operators\HeuristicLab.Operators.csproj">
       <Project>{A9983BA2-B3B2-475E-8E2C-62050B71D1C5}</Project>
Index: trunk/sources/HeuristicLab.sln
===================================================================
--- trunk/sources/HeuristicLab.sln	(revision 642)
+++ trunk/sources/HeuristicLab.sln	(revision 656)
@@ -44,12 +44,8 @@
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Charting.Data", "HeuristicLab.Charting.Data\HeuristicLab.Charting.Data.csproj", "{E0740131-AA3E-4A3F-BA03-C9FF8327F4EE}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Functions", "HeuristicLab.Functions\HeuristicLab.Functions.csproj", "{B95CA6E2-34BC-4430-994D-BD6E99375319}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Operators.Programmable", "HeuristicLab.Operators.Programmable\HeuristicLab.Operators.Programmable.csproj", "{E3CCBFC6-900C-41B6-AFB8-6646DB097435}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.SGA", "HeuristicLab.SGA\HeuristicLab.SGA.csproj", "{E39AF78A-9692-472B-B061-E2F1B1AB2C92}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.StructureIdentification", "HeuristicLab.StructureIdentification\HeuristicLab.StructureIdentification.csproj", "{5948F299-0A5E-43B9-8F17-2D15298EEC34}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Constraints", "HeuristicLab.Constraints\HeuristicLab.Constraints.csproj", "{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}"
 EndProject
@@ -101,4 +97,12 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP.SantaFe", "HeuristicLab.GP.SantaFe\HeuristicLab.GP.SantaFe.csproj", "{1F5FA590-1D2D-406C-BDBD-03BAECEA3C80}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP", "HeuristicLab.GP\HeuristicLab.GP.csproj", "{1F1CF3ED-374C-4288-995B-93F6B872F571}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP.StructureIdentification", "HeuristicLab.GP.StructureIdentification\HeuristicLab.GP.StructureIdentification.csproj", "{74223A32-C726-4978-BE78-37113A18373C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP.StructureIdentification.Classification", "HeuristicLab.GP.StructureIdentification.Classification\HeuristicLab.GP.StructureIdentification.Classification.csproj", "{7C20D100-8BEB-433A-9499-F075E2CB9297}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.GP.StructureIdentification.TimeSeries", "HeuristicLab.GP.StructureIdentification.TimeSeries\HeuristicLab.GP.StructureIdentification.TimeSeries.csproj", "{6084CFB5-733F-449D-9F92-2E40D13F0514}"
 EndProject
 Global
@@ -252,12 +256,4 @@
 		{E0740131-AA3E-4A3F-BA03-C9FF8327F4EE}.Release|x86.ActiveCfg = Release|x86
 		{E0740131-AA3E-4A3F-BA03-C9FF8327F4EE}.Release|x86.Build.0 = Release|x86
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Debug|x86.ActiveCfg = Debug|x86
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Debug|x86.Build.0 = Debug|x86
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Release|Any CPU.Build.0 = Release|Any CPU
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Release|x86.ActiveCfg = Release|x86
-		{B95CA6E2-34BC-4430-994D-BD6E99375319}.Release|x86.Build.0 = Release|x86
 		{E3CCBFC6-900C-41B6-AFB8-6646DB097435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{E3CCBFC6-900C-41B6-AFB8-6646DB097435}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -276,12 +272,4 @@
 		{E39AF78A-9692-472B-B061-E2F1B1AB2C92}.Release|x86.ActiveCfg = Release|x86
 		{E39AF78A-9692-472B-B061-E2F1B1AB2C92}.Release|x86.Build.0 = Release|x86
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Debug|x86.ActiveCfg = Debug|x86
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Debug|x86.Build.0 = Debug|x86
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Release|Any CPU.Build.0 = Release|Any CPU
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Release|x86.ActiveCfg = Release|x86
-		{5948F299-0A5E-43B9-8F17-2D15298EEC34}.Release|x86.Build.0 = Release|x86
 		{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{FCD62C6F-4793-4593-AE9A-0BDCA256EE99}.Debug|Any CPU.Build.0 = Debug|Any CPU
@@ -471,4 +459,34 @@
 		{1F5FA590-1D2D-406C-BDBD-03BAECEA3C80}.Release|x86.ActiveCfg = Release|x86
 		{1F5FA590-1D2D-406C-BDBD-03BAECEA3C80}.Release|x86.Build.0 = Release|x86
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Debug|x86.ActiveCfg = Debug|x86
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Debug|x86.Build.0 = Debug|x86
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Release|Any CPU.Build.0 = Release|Any CPU
+		{1F1CF3ED-374C-4288-995B-93F6B872F571}.Release|x86.ActiveCfg = Release|Any CPU
+		{74223A32-C726-4978-BE78-37113A18373C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{74223A32-C726-4978-BE78-37113A18373C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{74223A32-C726-4978-BE78-37113A18373C}.Debug|x86.ActiveCfg = Debug|x86
+		{74223A32-C726-4978-BE78-37113A18373C}.Debug|x86.Build.0 = Debug|x86
+		{74223A32-C726-4978-BE78-37113A18373C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{74223A32-C726-4978-BE78-37113A18373C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{74223A32-C726-4978-BE78-37113A18373C}.Release|x86.ActiveCfg = Release|Any CPU
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Debug|x86.ActiveCfg = Debug|x86
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Debug|x86.Build.0 = Debug|x86
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Release|x86.ActiveCfg = Release|x86
+		{7C20D100-8BEB-433A-9499-F075E2CB9297}.Release|x86.Build.0 = Release|x86
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Debug|x86.ActiveCfg = Debug|x86
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Debug|x86.Build.0 = Debug|x86
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Release|Any CPU.Build.0 = Release|Any CPU
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Release|x86.ActiveCfg = Release|x86
+		{6084CFB5-733F-449D-9F92-2E40D13F0514}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: trunk/sources/HeuristicLab/CopyAssemblies.cmd
===================================================================
--- trunk/sources/HeuristicLab/CopyAssemblies.cmd	(revision 642)
+++ trunk/sources/HeuristicLab/CopyAssemblies.cmd	(revision 656)
@@ -28,6 +28,9 @@
 copy %1\HeuristicLab.DistributedEngine\%2\HeuristicLab.DistributedEngine-3.2.dll .\plugins
 copy %1\HeuristicLab.Evolutionary\%2\HeuristicLab.Evolutionary-3.2.dll .\plugins
-copy %1\HeuristicLab.Functions\%2\HeuristicLab.Functions-3.2.dll .\plugins
+copy %1\HeuristicLab.GP\%2\HeuristicLab.GP-3.2.dll .\plugins
 copy %1\HeuristicLab.GP.SantaFe\%2\HeuristicLab.GP.SantaFe-3.2.dll .\plugins
+copy %1\HeuristicLab.GP.StructureIdentification\%2\HeuristicLab.GP.StructureIdentification-3.2.dll .\plugins
+copy %1\HeuristicLab.GP.StructureIdentification.Classification\%2\HeuristicLab.GP.StructureIdentification.Classification-3.2.dll .\plugins
+copy %1\HeuristicLab.GP.StructureIdentification.TimeSeries\%2\HeuristicLab.GP.StructureIdentification.TimeSeries-3.2.dll .\plugins
 copy %1\HeuristicLab.Grid\%2\HeuristicLab.Grid-3.2.dll .\plugins
 copy %1\HeuristicLab.Logging\%2\HeuristicLab.Logging-3.2.dll .\plugins
@@ -51,5 +54,4 @@
 copy %1\HeuristicLab.SQLite\"SQLite License.txt" .\plugins
 copy %1\HeuristicLab.SQLite\SQLite.NET.chm .\plugins
-copy %1\HeuristicLab.StructureIdentification\%2\HeuristicLab.StructureIdentification-3.2.dll .\plugins
 copy %1\HeuristicLab.TestFunctions\%2\HeuristicLab.TestFunctions-3.2.dll .\plugins
 copy %1\HeuristicLab.ThreadParallelEngine\%2\HeuristicLab.ThreadParallelEngine-3.2.dll .\plugins
