Index: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/AveragePercentageChangeEvaluator.cs
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/AveragePercentageChangeEvaluator.cs	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/AveragePercentageChangeEvaluator.cs	(revision 1301)
@@ -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.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.StructureIdentification.TimeSeries {
+  public class AvergePercentageChangeEvaluator : GPEvaluatorBase {
+    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 void Evaluate(IScope scope, BakedTreeEvaluator evaluator, HeuristicLab.DataAnalysis.Dataset dataset, int targetVariable, int start, int end, bool updateTargetValues) {
+      bool differential = GetVariableValue<BoolData>("Differential", scope, true).Data;
+      DoubleData apc = GetVariableValue<DoubleData>("APC", scope, false, false);
+      if (apc == null) {
+        apc = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("APC"), apc));
+      }
+
+      double percentageSum = 0;
+      for (int sample = start; sample < end; sample++) {
+        double prevOriginal;
+        double originalPercentageChange;
+        double estimatedPercentageChange;
+        if (differential) {
+          prevOriginal = dataset.GetValue(sample - 1, targetVariable);
+          originalPercentageChange = (dataset.GetValue(sample, targetVariable) - prevOriginal) / prevOriginal;
+          estimatedPercentageChange = (evaluator.Evaluate(sample) - prevOriginal) / prevOriginal;
+          if (updateTargetValues) {
+            dataset.SetValue(sample, targetVariable, estimatedPercentageChange * prevOriginal + prevOriginal);
+          }
+        } else {
+          originalPercentageChange = dataset.GetValue(sample, targetVariable);
+          estimatedPercentageChange = evaluator.Evaluate(sample);
+          if (updateTargetValues) {
+            dataset.SetValue(sample, targetVariable, 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: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/FunctionLibraryInjector.cs
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/FunctionLibraryInjector.cs	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/FunctionLibraryInjector.cs	(revision 1301)
@@ -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.Collections.Generic;
+using Core = HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Constraints;
+
+namespace HeuristicLab.GP.StructureIdentification.TimeSeries {
+  public class FunctionLibraryInjector : Core.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 Variable variable;
+    private 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 Core.VariableInfo(TARGETVARIABLE, "The target variable", typeof(IntData), Core.VariableKind.In));
+      AddVariableInfo(new Core.VariableInfo(AUTOREGRESSIVE, "Switch to turn on/off autoregressive modeling (wether to allow the target variable as input)", typeof(BoolData), Core.VariableKind.In));
+      AddVariableInfo(new Core.VariableInfo(ALLOWEDFEATURES, "List of indexes of allowed features", typeof(ItemList<IntData>), Core.VariableKind.In));
+      AddVariableInfo(new Core.VariableInfo(MINTIMEOFFSET, "Minimal time offset for all features", typeof(IntData), Core.VariableKind.In));
+      AddVariableInfo(new Core.VariableInfo(MAXTIMEOFFSET, "Maximal time offset for all feature", typeof(IntData), Core.VariableKind.In));
+      AddVariableInfo(new Core.VariableInfo(FUNCTIONLIBRARY, "Preconfigured default operator library", typeof(GPOperatorLibrary), Core.VariableKind.New));
+    }
+
+    public override Core.IOperation Apply(Core.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 Core.Variable(scope.TranslateName(FUNCTIONLIBRARY), operatorLibrary));
+      return null;
+    }
+
+    private void InitDefaultOperatorLibrary() {
+      variable = new Variable();
+      differential = new Differential();
+      Constant constant = new Constant();
+
+      Addition addition = new Addition();
+      And and = new And();
+      Average average = new Average();
+      Cosinus cosinus = new Cosinus();
+      Division division = new Division();
+      Equal equal = new Equal();
+      Exponential exponential = new Exponential();
+      GreaterThan greaterThan = new GreaterThan();
+      IfThenElse ifThenElse = new IfThenElse();
+      LessThan lessThan = new LessThan();
+      Logarithm logarithm = new Logarithm();
+      Multiplication multiplication = new Multiplication();
+      Not not = new Not();
+      Or or = new Or();
+      Power power = new Power();
+      Signum signum = new Signum();
+      Sinus sinus = new Sinus();
+      Sqrt sqrt = new Sqrt();
+      Subtraction subtraction = new Subtraction();
+      Tangens tangens = new Tangens();
+      Xor xor = new Xor();
+
+      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(Core.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(Core.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: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLab.GP.StructureIdentification.TimeSeries.csproj	(revision 1301)
@@ -0,0 +1,125 @@
+﻿<?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.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6084CFB5-733F-449D-9F92-2E40D13F0514}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.GP.StructureIdentification.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>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLabGPTimeSeriesPlugin.cs
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLabGPTimeSeriesPlugin.cs	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/HeuristicLabGPTimeSeriesPlugin.cs	(revision 1301)
@@ -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.StructureIdentification.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: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/ProfitEvaluator.cs
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/ProfitEvaluator.cs	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/ProfitEvaluator.cs	(revision 1301)
@@ -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.Data;
+using HeuristicLab.GP.StructureIdentification;
+
+namespace HeuristicLab.GP.StructureIdentification.TimeSeries {
+  public class ProfitEvaluator : GPEvaluatorBase {
+    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 void Evaluate(IScope scope, BakedTreeEvaluator evaluator, HeuristicLab.DataAnalysis.Dataset dataset, int targetVariable, int start, int end, bool updateTargetValues) {
+      int exchangeRateVarIndex = GetVariableValue<IntData>("ExchangeRate", scope, true).Data;
+      double transactionCost = GetVariableValue<DoubleData>("TransactionCost", scope, true).Data;
+      DoubleData profit = GetVariableValue<DoubleData>("Profit", scope, false, false);
+      if (profit == null) {
+        profit = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("Profit"), profit));
+      }
+
+      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 = dataset.GetValue(sample, targetVariable);
+        double estimatedPercentageChange = evaluator.Evaluate(sample);
+        if (updateTargetValues) {
+          dataset.SetValue(sample, targetVariable, 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: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/Properties/AssemblyInfo.frame
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/Properties/AssemblyInfo.frame	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/Properties/AssemblyInfo.frame	(revision 1301)
@@ -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: branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/TheilInequalityCoefficientEvaluator.cs
===================================================================
--- branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/TheilInequalityCoefficientEvaluator.cs	(revision 1301)
+++ branches/plugins/HeuristicLab.GP.StructureIdentification.TimeSeries/3.2/TheilInequalityCoefficientEvaluator.cs	(revision 1301)
@@ -0,0 +1,119 @@
+#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;
+using HeuristicLab.DataAnalysis;
+
+namespace HeuristicLab.GP.StructureIdentification.TimeSeries {
+  public class TheilInequalityCoefficientEvaluator : GPEvaluatorBase {
+    public override string Description {
+      get {
+        return @"Evaluates 'FunctionTree' for all samples of 'Dataset' and calculates
+the 'Theil inequality coefficient (Theil's U2 not U1!)' of estimated values vs. real values of 'TargetVariable'.
+
+U2 = Sqrt(1/N * Sum(P_t - A_t)^2 ) / Sqrt(1/N * Sum(A_t)^2 ) 
+
+where P_t is the predicted change of the target variable and A_t is the measured (original) change.
+(P_t = y'_t - y_(t-1), A_t = y_t - y_(t-1)).
+
+U2 is 0 for a perfect prediction and 1 for the naive model y'_t = y_(t-1). An U2 > 1 means the
+model is worse than the naive model (=> model is useless).";
+      }
+    }
+
+    public TheilInequalityCoefficientEvaluator()
+      : base() {
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficient", "Theil's inequality coefficient (U2) of the model", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficientBias", "Bias proportion of Theil's inequality coefficient", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficientVariance", "Variance proportion of Theil's inequality coefficient", typeof(DoubleData), VariableKind.New));
+      AddVariableInfo(new VariableInfo("TheilInequalityCoefficientCovariance", "Covariance proportion of Theil's inequality coefficient", typeof(DoubleData), VariableKind.New));
+    }
+
+    public override void Evaluate(IScope scope, BakedTreeEvaluator evaluator, Dataset dataset, int targetVariable, int start, int end, bool updateTargetValues) {
+      #region create result variables
+      DoubleData theilInequaliy = GetVariableValue<DoubleData>("TheilInequalityCoefficient", scope, false, false);
+      if (theilInequaliy == null) {
+        theilInequaliy = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficient"), theilInequaliy));
+      }
+      DoubleData uBias = GetVariableValue<DoubleData>("TheilInequalityCoefficientBias", scope, false, false);
+      if (uBias == null) {
+        uBias = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficientBias"), uBias));
+      }
+      DoubleData uVariance = GetVariableValue<DoubleData>("TheilInequalityCoefficientVariance", scope, false, false);
+      if (uVariance == null) {
+        uVariance = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficientVariance"), uVariance));
+      }
+      DoubleData uCovariance = GetVariableValue<DoubleData>("TheilInequalityCoefficientCovariance", scope, false, false);
+      if (uCovariance == null) {
+        uCovariance = new DoubleData();
+        scope.AddVariable(new HeuristicLab.Core.Variable(scope.TranslateName("TheilInequalityCoefficientCovariance"), uCovariance));
+      }
+      #endregion
+
+      double errorsSquaredSum = 0.0;
+      double originalSquaredSum = 0.0;
+      double[] estimatedChanges = new double[end - start];
+      double[] originalChanges = new double[end - start];
+      int nSamples = 0;
+      for (int sample = start; sample < end; sample++) {
+        double prevValue = dataset.GetValue(sample - 1, targetVariable);
+        double estimatedChange = evaluator.Evaluate(sample) - prevValue;
+        double originalChange = dataset.GetValue(sample, targetVariable) - prevValue;
+        if (updateTargetValues) {
+          dataset.SetValue(sample, targetVariable, estimatedChange + prevValue);
+        }
+        if (!double.IsNaN(originalChange) && !double.IsInfinity(originalChange)) {
+          double error = estimatedChange - originalChange;
+          errorsSquaredSum += error * error;
+          originalSquaredSum += originalChange * originalChange;
+          estimatedChanges[sample - start] = estimatedChange;
+          originalChanges[sample - start] = originalChange;
+          nSamples++;
+        }
+      }
+      double quality = Math.Sqrt(errorsSquaredSum / nSamples) / Math.Sqrt(originalSquaredSum / nSamples);
+      if (double.IsNaN(quality) || double.IsInfinity(quality))
+        quality = double.MaxValue;
+      theilInequaliy.Data = quality; // U2
+
+      // decomposition into U_bias + U_variance + U_covariance parts
+      double bias = Statistics.Mean(estimatedChanges) - Statistics.Mean(originalChanges);
+      bias *= bias; // squared
+      uBias.Data = bias / (errorsSquaredSum / nSamples);
+
+      double variance = Statistics.StandardDeviation(estimatedChanges) - Statistics.StandardDeviation(originalChanges);
+      variance *= variance; // squared
+      uVariance.Data = variance / (errorsSquaredSum / nSamples);
+
+      // all parts add up to one so I don't have to calculate the correlation coefficient for the covariance proportion
+      uCovariance.Data = 1.0 - uBias.Data - uVariance.Data;
+    }
+  }
+}
