Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Algorithms.DataAnalysis/3.4/Linear/LinearTimeSeriesPrognosis.cs	(revision 7120)
@@ -142,5 +142,5 @@
       }
 
-      SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicTimeSeriesPrognosisInterpreter(problemData.TargetVariables.ToArray())), (ITimeSeriesPrognosisProblemData)problemData.Clone());
+      SymbolicTimeSeriesPrognosisSolution solution = new SymbolicTimeSeriesPrognosisSolution(new SymbolicTimeSeriesPrognosisModel(tree, new SymbolicDataAnalysisExpressionTreeInterpreter(), problemData.TargetVariables.ToArray()), (ITimeSeriesPrognosisProblemData)problemData.Clone());
       solution.Model.Name = "Linear Time-Series Prognosis Model";
       return solution;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Symbols/StartSymbol.cs	(revision 7120)
@@ -26,9 +26,9 @@
   [StorableClass]
   [Item(StartSymbol.StartSymbolName, StartSymbol.StartSymbolDescription)]
-  public sealed class StartSymbol : Symbol, IReadOnlySymbol {
+  public sealed class StartSymbol : Symbol {
     public const string StartSymbolName = "StartSymbol";
     public const string StartSymbolDescription = "Special symbol that represents the starting node of the result producing branch of a symbolic expression tree.";
     private const int minimumArity = 1;
-    private const int maximumArity = 1;
+    private const int maximumArity = 255;
 
     public override int MinimumArity {
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 7120)
@@ -111,24 +111,6 @@
   <ItemGroup>
     <Compile Include="Plugin.cs" />
-    <Compile Include="SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
-      <DependentUpon>SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
-    </Compile>
-    <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="SymbolicTimeSeriesPrognosisSolutionView.Designer.cs">
-      <DependentUpon>SymbolicTimeSeriesPrognosisSolutionView.cs</DependentUpon>
-    </Compile>
     <None Include="HeuristicLab.snk" />
     <None Include="Plugin.cs.frame" />
-    <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs">
-      <SubType>UserControl</SubType>
-    </Compile>
-    <Compile Include="InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.Designer.cs">
-      <DependentUpon>InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs</DependentUpon>
-    </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 7120)
@@ -111,5 +111,4 @@
   <ItemGroup>
     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisInterpreterOperator.cs" />
-    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisInterpreter.cs" />
     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisEvaluator.cs" />
     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisModel.cs" />
@@ -122,5 +121,4 @@
     <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs" />
     <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs" />
-    <Compile Include="SymbolicTimeSeriesPrognosisInterpreter.cs" />
     <Compile Include="SymbolicTimeSeriesPrognosisModel.cs" />
     <Compile Include="SymbolicTimeSeriesPrognosisSolution.cs" />
@@ -139,4 +137,8 @@
       <Name>HeuristicLab.Collections-3.3</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
       <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
@@ -182,4 +184,8 @@
       <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
       <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
     </ProjectReference>
   </ItemGroup>
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisInterpreter.cs	(revision 7100)
+++ 	(revision )
@@ -1,30 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 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.Encodings.SymbolicExpressionTreeEncoding;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
-  public interface ISymbolicTimeSeriesPrognosisInterpreter : ISymbolicDataAnalysisExpressionTreeInterpreter {
-    IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, int horizon);
-  }
-}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisEvaluator.cs	(revision 7120)
@@ -20,7 +20,10 @@
 #endregion
 
+using HeuristicLab.Core;
+using HeuristicLab.Data;
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
   public interface ISymbolicTimeSeriesPrognosisEvaluator : ISymbolicDataAnalysisEvaluator<ITimeSeriesPrognosisProblemData> {
+    IValueLookupParameter<IntValue> HorizonParameter { get; }
   }
 }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisInterpreterOperator.cs	(revision 7120)
@@ -24,5 +24,5 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
   public interface ISymbolicTimeSeriesPrognosisInterpreterOperator : IOperator {
-    ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter { get; }
+    ILookupParameter<ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter { get; }
   }
 }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognosisModel.cs	(revision 7120)
@@ -22,5 +22,7 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
-  public interface ISymbolicTimeSeriesPrognosisModel : ITimeSeriesPrognosisModel, ISymbolicDataAnalysisModel {
+  public interface ISymbolicTimeSeriesPrognosisModel : ITimeSeriesPrognosisModel {
+    ISymbolicExpressionTree SymbolicExpressionTree { get; }
+    ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter { get; }
   }
 }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 7120)
@@ -22,7 +22,16 @@
 
 using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
   public abstract class SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData>, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
+    private const string HorizonParameterName = "Horizon";
+
+    public IValueLookupParameter<IntValue> HorizonParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[HorizonParameterName]; }
+    }
+
     [StorableConstructor]
     protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator(bool deserializing) : base(deserializing) { }
@@ -31,5 +40,8 @@
     }
 
-    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator() : base() { }
+    protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<IntValue>(HorizonParameterName, "The time interval for which the prognosis should be calculated.", new IntValue(1)));
+    }
   }
 }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 7120)
@@ -20,5 +20,7 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -48,5 +50,9 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
+        solution,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        ProblemDataParameter.ActualValue,
+        rows, HorizonParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -54,14 +60,20 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
-      OnlineMeanAndVarianceCalculator meanCalculator = new OnlineMeanAndVarianceCalculator();
+    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
+      var allPredictedContinuations = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, problemData.TargetVariables.ToArray(), rows, horizon);
+      var meanCalculator = new OnlineMeanAndVarianceCalculator();
+      var allPredictedContinuationsEnumerator = allPredictedContinuations.GetEnumerator();
       foreach (var targetVariable in problemData.TargetVariables) {
-        IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(targetVariable, rows);
-        IEnumerable<double> boundedEstimationValues = estimatedValues.LimitToRange(lowerEstimationLimit,
-                                                                                   upperEstimationLimit);
-        OnlineCalculatorError errorState;
-        meanCalculator.Add(OnlineMeanSquaredErrorCalculator.Calculate(originalValues, boundedEstimationValues, out errorState));
-        if (errorState != OnlineCalculatorError.None) return double.NaN;
+        if (!allPredictedContinuationsEnumerator.MoveNext()) throw new InvalidOperationException();
+        var actualContinuations = from r in rows
+                                  select problemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(r, horizon));
+        var actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+        var predictedContinuationsEnumerator = allPredictedContinuationsEnumerator.Current.GetEnumerator();
+        while (actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+          OnlineCalculatorError errorState;
+          meanCalculator.Add(OnlineMeanSquaredErrorCalculator.Calculate(predictedContinuationsEnumerator.Current.LimitToRange(lowerEstimationLimit, upperEstimationLimit),
+                                                                        actualContinuationsEnumerator.Current, out errorState));
+          if (errorState != OnlineCalculatorError.None) return double.NaN;
+        }
       }
       return meanCalculator.Mean;
@@ -69,11 +81,12 @@
 
     public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
-      SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = context;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      HorizonParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
 
-
-      SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = null;
+      HorizonParameter.ExecutionContext = null;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectivePearsonRSquaredEvaluator.cs	(revision 7120)
@@ -20,5 +20,7 @@
 #endregion
 
+using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -48,5 +50,8 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, solution, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, ProblemDataParameter.ActualValue, rows);
+      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, solution,
+        EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
+        ProblemDataParameter.ActualValue,
+        rows, HorizonParameter.ActualValue.Value);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -54,12 +59,22 @@
     }
 
-    public static double Calculate(ISymbolicDataAnalysisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
-      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows);
+    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
+      var allPredictedContinuations =
+        interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, problemData.TargetVariables.ToArray(),
+                                                    rows, horizon).ToArray();
+
       var meanCalculator = new OnlineMeanAndVarianceCalculator();
+      int i = 0;
       foreach (var targetVariable in problemData.TargetVariables) {
-        IEnumerable<double> originalValues = problemData.Dataset.GetDoubleValues(targetVariable, rows);
+        var actualContinuations = from r in rows
+                                  select problemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(r, horizon));
+        var startValues = problemData.Dataset.GetDoubleValues(targetVariable, rows.Select(r => r - 1));
         OnlineCalculatorError errorState;
-        meanCalculator.Add(OnlinePearsonsRSquaredCalculator.Calculate(estimatedValues, originalValues, out errorState));
-        if (errorState != OnlineCalculatorError.None) return 0.0;
+        meanCalculator.Add(OnlineTheilsUStatisticCalculator.Calculate(
+          startValues,
+          allPredictedContinuations.Select(v => v.ElementAt(i)),
+          actualContinuations, out errorState));
+        if (errorState != OnlineCalculatorError.None) return double.NaN;
+        i++;
       }
       return meanCalculator.Mean;
@@ -67,10 +82,12 @@
 
     public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
-      SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = context;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = context;
       EstimationLimitsParameter.ExecutionContext = context;
+      HorizonParameter.ExecutionContext = context;
 
-      double r2 = Calculate(SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows);
+      double r2 = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
 
-      SymbolicTimeSeriesPrognosisInterpreterParameter.ExecutionContext = null;
+      HorizonParameter.ExecutionContext = null;
+      SymbolicDataAnalysisTreeInterpreterParameter.ExecutionContext = null;
       EstimationLimitsParameter.ExecutionContext = null;
 
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 7120)
@@ -31,5 +31,4 @@
   [Creatable("Problems")]
   public class SymbolicTimeSeriesPrognosisSingleObjectiveProblem : SymbolicDataAnalysisSingleObjectiveProblem<ITimeSeriesPrognosisProblemData, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator, ISymbolicDataAnalysisSolutionCreator>, ITimeSeriesPrognosisProblem {
-    private const double PunishmentFactor = 10;
     private const int InitialMaximumTreeDepth = 8;
     private const int InitialMaximumTreeLength = 25;
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 7120)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -34,7 +35,7 @@
   [StorableClass]
   public sealed class SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer : SymbolicDataAnalysisSingleObjectiveTrainingBestSolutionAnalyzer<ISymbolicTimeSeriesPrognosisSolution>,
-  ISymbolicTimeSeriesPrognosisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
+  ISymbolicDataAnalysisInterpreterOperator, ISymbolicDataAnalysisBoundedOperator {
     private const string ProblemDataParameterName = "ProblemData";
-    private const string SymbolicTimeSeriesPrognosisInterpreterParameterName = "SymbolicTimeSeriesPrognosisInterpreter";
+    private const string SymbolicDataAnalysisTreeInterpreterParameterName = "SymbolicDataAnalysisTreeInterpreter";
     private const string EstimationLimitsParameterName = "EstimationLimits";
     private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
@@ -43,6 +44,6 @@
       get { return (ILookupParameter<ITimeSeriesPrognosisProblemData>)Parameters[ProblemDataParameterName]; }
     }
-    public ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter> SymbolicTimeSeriesPrognosisInterpreterParameter {
-      get { return (ILookupParameter<ISymbolicTimeSeriesPrognosisInterpreter>)Parameters[SymbolicTimeSeriesPrognosisInterpreterParameterName]; }
+    public ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter> SymbolicDataAnalysisTreeInterpreterParameter {
+      get { return (ILookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>)Parameters[SymbolicDataAnalysisTreeInterpreterParameterName]; }
     }
     public IValueLookupParameter<DoubleLimit> EstimationLimitsParameter {
@@ -66,5 +67,5 @@
       : base() {
       Parameters.Add(new LookupParameter<ITimeSeriesPrognosisProblemData>(ProblemDataParameterName, "The problem data for the symbolic regression solution."));
-      Parameters.Add(new LookupParameter<ISymbolicTimeSeriesPrognosisInterpreter>(SymbolicTimeSeriesPrognosisInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
+      Parameters.Add(new LookupParameter<ISymbolicDataAnalysisExpressionTreeInterpreter>(SymbolicDataAnalysisTreeInterpreterParameterName, "The symbolic time series prognosis interpreter for the symbolic expression tree."));
       Parameters.Add(new ValueLookupParameter<DoubleLimit>(EstimationLimitsParameterName, "The lower and upper limit for the estimated values produced by the symbolic regression model."));
       Parameters.Add(new ValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the produced symbolic regression solution should be linearly scaled.", new BoolValue(true)));
@@ -75,5 +76,5 @@
 
     protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicTimeSeriesPrognosisInterpreterParameter.ActualValue);
+      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariables.ToArray());
       if (ApplyLinearScaling.Value)
         SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisInterpreter.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisInterpreter.cs	(revision 7120)
@@ -33,5 +33,5 @@
   [StorableClass]
   [Item("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
-  public sealed class SymbolicTimeSeriesPrognosisInterpreter : ParameterizedNamedItem, ISymbolicTimeSeriesPrognosisInterpreter {
+  public sealed class SymbolicTimeSeriesPrognosisInterpreter : ParameterizedNamedItem, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     #region private classes
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 7120)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using HeuristicLab.Common;
@@ -33,8 +34,28 @@
   [StorableClass]
   [Item(Name = "Symbolic Time-Series Prognosis Model", Description = "Represents a symbolic time series prognosis model.")]
-  public class SymbolicTimeSeriesPrognosisModel : SymbolicDataAnalysisModel, ISymbolicTimeSeriesPrognosisModel {
-    public new ISymbolicTimeSeriesPrognosisInterpreter Interpreter {
-      get { return (ISymbolicTimeSeriesPrognosisInterpreter)base.Interpreter; }
+  public class SymbolicTimeSeriesPrognosisModel : NamedItem, ISymbolicTimeSeriesPrognosisModel {
+    public override Image ItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
     }
+
+    #region properties
+
+    [Storable]
+    private ISymbolicExpressionTree symbolicExpressionTree;
+    public ISymbolicExpressionTree SymbolicExpressionTree {
+      get { return symbolicExpressionTree; }
+    }
+
+    [Storable]
+    private ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter;
+    public ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter Interpreter {
+      get { return interpreter; }
+    }
+
+    #endregion
+
+    [Storable]
+    private string[] targetVariables;
+
 
     [StorableConstructor]
@@ -42,7 +63,13 @@
     protected SymbolicTimeSeriesPrognosisModel(SymbolicTimeSeriesPrognosisModel original, Cloner cloner)
       : base(original, cloner) {
+      this.symbolicExpressionTree = cloner.Clone(original.symbolicExpressionTree);
+      this.interpreter = cloner.Clone(original.interpreter);
     }
-    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisInterpreter interpreter)
-      : base(tree, interpreter) {
+    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, IEnumerable<string> targetVariables)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.symbolicExpressionTree = tree;
+      this.interpreter = interpreter; this.targetVariables = targetVariables.ToArray();
     }
 
@@ -52,5 +79,5 @@
 
     public IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon) {
-      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows, horizon);
+      return Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, targetVariables, rows, horizon);
     }
 
@@ -68,5 +95,5 @@
       int i = 0;
       int horizon = 1;
-      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows, horizon)
+      var estimatedValues = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, problemData.TargetVariables.ToArray(), rows, horizon)
         .ToArray();
       foreach (var targetVariable in targetVariables) {
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 7120)
@@ -126,4 +126,5 @@
     <Compile Include="Creators\SymbolicDataAnalysisExpressionRampedHalfAndHalfTreeCreator.cs" />
     <Compile Include="Creators\SymbolicDataAnalysisExpressionTreeCreator.cs" />
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs" />
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7120)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public interface ISymbolicDataAnalysisExpressionTreeInterpreter : INamedItem {
+  public interface ISymbolicDataAnalysisExpressionTreeInterpreter : ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
     IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows);
   }
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7120)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7120)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 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.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : INamedItem  {
+    IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon);
+  }
+}
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 7120)
@@ -222,4 +222,7 @@
       }
     }
+    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
+      throw new NotImplementedException();
+    }
 
     private void CompileInstructions(ILGenerator il, InterpreterState state, Dataset ds) {
Index: branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7100)
+++ branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7120)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -32,5 +33,6 @@
   [StorableClass]
   [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
-  public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
+  public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem,
+    ISymbolicDataAnalysisExpressionTreeInterpreter, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     #region private classes
@@ -199,4 +201,10 @@
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
+      return from prog in GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows, 1)
+             select prog.First().First();
+    }
+
+    // for each row for each target variable one prognosis (=enumerable of future values)
+    public IEnumerable<IEnumerable<IEnumerable<double>>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
         throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
@@ -223,25 +231,46 @@
       var state = new InterpreterState(code, necessaryArgStackSize);
 
+      int nComponents = tree.Root.GetSubtree(0).SubtreeCount;
+      // produce a n-step forecast for each target variable for all rows
+      var cachedPrognosedValues = new Dictionary<string, double[]>();
+      foreach (var targetVariable in targetVariables)
+        cachedPrognosedValues[targetVariable] = new double[horizon];
       foreach (var rowEnum in rows) {
         int row = rowEnum;
-        state.Reset();
-        yield return Evaluate(dataset, ref row, state);
-      }
-    }
-
-    private double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
+        List<double[]> vProgs = new List<double[]>();
+        foreach (var horizonRow in Enumerable.Range(row, horizon)) {
+          int localRow = horizonRow; // create a local variable for the ref parameter
+          var vPrognosis = from i in Enumerable.Range(0, nComponents)
+                           select Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
+
+          var vPrognosisArr = vPrognosis.ToArray();
+          vProgs.Add(vPrognosisArr);
+          // set cachedValues for prognosis of future values
+          for (int i = 0; i < vPrognosisArr.Length; i++)
+            cachedPrognosedValues[targetVariables[i]][horizonRow - row] = vPrognosisArr[i];
+
+          state.Reset();
+        }
+
+        yield return from component in Enumerable.Range(0, nComponents)
+                     select from prognosisStep in Enumerable.Range(0, vProgs.Count)
+                            select vProgs[prognosisStep][component];
+      }
+    }
+
+    private double Evaluate(Dataset dataset, ref int row, int lastObservedRow, InterpreterState state, Dictionary<string, double[]> cachedPrognosedValues) {
       Instruction currentInstr = state.NextInstruction();
       switch (currentInstr.opCode) {
         case OpCodes.Add: {
-            double s = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s += Evaluate(dataset, ref row, state);
+            double s = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             return s;
           }
         case OpCodes.Sub: {
-            double s = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              s -= Evaluate(dataset, ref row, state);
+            double s = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s -= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             if (currentInstr.nArguments == 1) s = -s;
@@ -249,14 +278,14 @@
           }
         case OpCodes.Mul: {
-            double p = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p *= Evaluate(dataset, ref row, state);
+            double p = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p *= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             return p;
           }
         case OpCodes.Div: {
-            double p = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              p /= Evaluate(dataset, ref row, state);
+            double p = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p /= Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             if (currentInstr.nArguments == 1) p = 1.0 / p;
@@ -264,49 +293,49 @@
           }
         case OpCodes.Average: {
-            double sum = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              sum += Evaluate(dataset, ref row, state);
+            double sum = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             return sum / currentInstr.nArguments;
           }
         case OpCodes.Cos: {
-            return Math.Cos(Evaluate(dataset, ref row, state));
+            return Math.Cos(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
           }
         case OpCodes.Sin: {
-            return Math.Sin(Evaluate(dataset, ref row, state));
+            return Math.Sin(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
           }
         case OpCodes.Tan: {
-            return Math.Tan(Evaluate(dataset, ref row, state));
+            return Math.Tan(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
           }
         case OpCodes.Power: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Math.Round(Evaluate(dataset, ref row, state));
+            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
             return Math.Pow(x, y);
           }
         case OpCodes.Root: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Math.Round(Evaluate(dataset, ref row, state));
+            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
             return Math.Pow(x, 1 / y);
           }
         case OpCodes.Exp: {
-            return Math.Exp(Evaluate(dataset, ref row, state));
+            return Math.Exp(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
           }
         case OpCodes.Log: {
-            return Math.Log(Evaluate(dataset, ref row, state));
+            return Math.Log(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
           }
         case OpCodes.IfThenElse: {
-            double condition = Evaluate(dataset, ref row, state);
+            double condition = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             double result;
             if (condition > 0.0) {
-              result = Evaluate(dataset, ref row, state); SkipInstructions(state);
+              result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); SkipInstructions(state);
             } else {
-              SkipInstructions(state); result = Evaluate(dataset, ref row, state);
+              SkipInstructions(state); result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             return result;
           }
         case OpCodes.AND: {
-            double result = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result > 0.0) result = Evaluate(dataset, ref row, state);
+            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result > 0.0) result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
               else {
                 SkipInstructions(state);
@@ -316,7 +345,7 @@
           }
         case OpCodes.OR: {
-            double result = Evaluate(dataset, ref row, state);
-            for (int i = 1; i < currentInstr.nArguments; i++) {
-              if (result <= 0.0) result = Evaluate(dataset, ref row, state);
+            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              if (result <= 0.0) result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
               else {
                 SkipInstructions(state);
@@ -326,15 +355,15 @@
           }
         case OpCodes.NOT: {
-            return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
+            return Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues) > 0.0 ? -1.0 : 1.0;
           }
         case OpCodes.GT: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Evaluate(dataset, ref row, state);
+            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             if (x > y) return 1.0;
             else return -1.0;
           }
         case OpCodes.LT: {
-            double x = Evaluate(dataset, ref row, state);
-            double y = Evaluate(dataset, ref row, state);
+            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             if (x < y) return 1.0;
             else return -1.0;
@@ -343,5 +372,5 @@
             var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
             row += timeLagTreeNode.Lag;
-            double result = Evaluate(dataset, ref row, state);
+            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             row -= timeLagTreeNode.Lag;
             return result;
@@ -353,9 +382,9 @@
             for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
               row += Math.Sign(timeLagTreeNode.Lag);
-              sum += Evaluate(dataset, ref row, state);
+              sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
               state.ProgramCounter = savedPc;
             }
             row -= timeLagTreeNode.Lag;
-            sum += Evaluate(dataset, ref row, state);
+            sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             return sum;
           }
@@ -367,11 +396,11 @@
         case OpCodes.Derivative: {
             int savedPc = state.ProgramCounter;
-            double f_0 = Evaluate(dataset, ref row, state); row--;
+            double f_0 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
             state.ProgramCounter = savedPc;
-            double f_1 = Evaluate(dataset, ref row, state); row -= 2;
+            double f_1 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row -= 2;
             state.ProgramCounter = savedPc;
-            double f_3 = Evaluate(dataset, ref row, state); row--;
+            double f_3 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
             state.ProgramCounter = savedPc;
-            double f_4 = Evaluate(dataset, ref row, state);
+            double f_4 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             row += 4;
 
@@ -382,5 +411,5 @@
             double[] argValues = new double[currentInstr.nArguments];
             for (int i = 0; i < currentInstr.nArguments; i++) {
-              argValues[i] = Evaluate(dataset, ref row, state);
+              argValues[i] = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
             }
             // push on argument values on stack 
@@ -392,5 +421,5 @@
             state.ProgramCounter = (ushort)currentInstr.iArg0;
             // evaluate the function
-            double v = Evaluate(dataset, ref row, state);
+            double v = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
 
             // delete the stack frame
@@ -408,5 +437,6 @@
               return double.NaN;
             var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-            return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
+            if (row <= lastObservedRow || !cachedPrognosedValues.ContainsKey(variableTreeNode.VariableName)) return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
+            else return cachedPrognosedValues[variableTreeNode.VariableName][row - lastObservedRow - 1] * variableTreeNode.Weight;
           }
         case OpCodes.LagVariable: {
@@ -415,5 +445,6 @@
             if (actualRow < 0 || actualRow >= dataset.Rows)
               return double.NaN;
-            return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
+            if (actualRow <= lastObservedRow || !cachedPrognosedValues.ContainsKey(laggedVariableTreeNode.VariableName)) return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
+            else return cachedPrognosedValues[laggedVariableTreeNode.VariableName][actualRow - lastObservedRow - 1] * laggedVariableTreeNode.Weight;
           }
         case OpCodes.Constant: {
@@ -428,10 +459,15 @@
               return double.NaN;
             var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
-            double variableValue = ((IList<double>)currentInstr.iArg0)[row];
+            double variableValue;
+            if (row <= lastObservedRow || !cachedPrognosedValues.ContainsKey(variableConditionTreeNode.VariableName))
+              variableValue = ((IList<double>)currentInstr.iArg0)[row];
+            else
+              variableValue = cachedPrognosedValues[variableConditionTreeNode.VariableName][row - lastObservedRow - 1];
+
             double x = variableValue - variableConditionTreeNode.Threshold;
             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
 
-            double trueBranch = Evaluate(dataset, ref row, state);
-            double falseBranch = Evaluate(dataset, ref row, state);
+            double trueBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double falseBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
 
             return trueBranch * p + falseBranch * (1 - p);
