Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 8435)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 8436)
@@ -53,5 +53,4 @@
           var invokeNode = (InvokeFunctionTreeNode)instr.dynamicNode;
           instr.iArg0 = entryPoint[invokeNode.Symbol.FunctionName];
-          code[i] = instr;
         }
       }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs	(revision 8435)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs	(revision 8436)
@@ -24,15 +24,15 @@
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
   public class InterpreterState {
-    private double[] argumentStack;
+    private readonly double[] argumentStack;
     private int argumentStackPointer;
-    private Instruction[] code;
-    private int pc;
-    public int ProgramCounter {
-      get { return pc; }
-      set { pc = value; }
-    }
+    private readonly Instruction[] code;
+
+    public int ProgramCounter { get; set; }
+    public bool InLaggedContext { get; set; }
+
     public InterpreterState(Instruction[] code, int argumentStackSize) {
       this.code = code;
-      this.pc = 0;
+      this.ProgramCounter = 0;
+      this.InLaggedContext = false;
       if (argumentStackSize > 0) {
         this.argumentStack = new double[argumentStackSize];
@@ -42,10 +42,11 @@
 
     public void Reset() {
-      this.pc = 0;
+      this.ProgramCounter = 0;
       this.argumentStackPointer = 0;
+      this.InLaggedContext = false;
     }
 
     public Instruction NextInstruction() {
-      return code[pc++];
+      return code[ProgramCounter++];
     }
     // skips a whole branch
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 8435)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 8436)
@@ -84,5 +84,5 @@
 
     private static Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
-      { typeof(Addition), OpCodes.Add },
+       { typeof(Addition), OpCodes.Add },
       { typeof(Subtraction), OpCodes.Sub },
       { typeof(Multiplication), OpCodes.Mul },
@@ -127,5 +127,5 @@
       { typeof(Norm), OpCodes.Norm},
       { typeof(Erf), OpCodes.Erf},
-      { typeof(Bessel), OpCodes.Bessel}      
+      { typeof(Bessel), OpCodes.Bessel}   
     };
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 8435)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeILEmittingInterpreter.cs	(revision 8436)
@@ -35,8 +35,10 @@
   [StorableClass]
   [Item("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.")]
-  public sealed class SymbolicDataAnalysisExpressionTreeILEmittingInterpreter : ParameterizedNamedItem,
-                                                                                ISymbolicDataAnalysisExpressionTreeInterpreter {
-    private static MethodInfo listGetValue =
-      typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod();
+  public sealed class SymbolicDataAnalysisExpressionTreeILEmittingInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
+    private static readonly Type thisType = typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter);
+    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns);
+
+    #region method infos
+    private static MethodInfo listGetValue = typeof(IList<double>).GetProperty("Item", new Type[] { typeof(int) }).GetGetMethod();
 
     private static MethodInfo cos = typeof(Math).GetMethod("Cos", new Type[] { typeof(double) });
@@ -49,6 +51,4 @@
     private static MethodInfo sqrt = typeof(Math).GetMethod("Sqrt", new Type[] { typeof(double) });
 
-    internal delegate double CompiledFunction(int sampleIndex, IList<double>[] columns, IList<double>[] cachedValues, int cacheStartIndex);
-    private static Type thisType = typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter);
     private static MethodInfo airyA = thisType.GetMethod("AiryA", new Type[] { typeof(double) });
     private static MethodInfo airyB = thisType.GetMethod("AiryB", new Type[] { typeof(double) });
@@ -66,155 +66,8 @@
     private static MethodInfo erf = thisType.GetMethod("Erf", new Type[] { typeof(double) });
     private static MethodInfo bessel = thisType.GetMethod("Bessel", new Type[] { typeof(double) });
-
-    
+    #endregion
 
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-
-    #region private classes
-
-    private class InterpreterState {
-      private Instruction[] code;
-      private int pc;
-
-      public int ProgramCounter {
-        get { return pc; }
-        set { pc = value; }
-      }
-
-      private bool inLaggedContext;
-
-      public bool InLaggedContext {
-        get { return inLaggedContext; }
-        set { inLaggedContext = value; }
-      }
-
-      internal InterpreterState(Instruction[] code) {
-        this.inLaggedContext = false;
-        this.code = code;
-        this.pc = 0;
-      }
-
-      internal Instruction NextInstruction() {
-        return code[pc++];
-      }
-    }
-
-    private class OpCodes {
-      public const byte Add = 1;
-      public const byte Sub = 2;
-      public const byte Mul = 3;
-      public const byte Div = 4;
-
-      public const byte Sin = 5;
-      public const byte Cos = 6;
-      public const byte Tan = 7;
-
-      public const byte Log = 8;
-      public const byte Exp = 9;
-
-      public const byte IfThenElse = 10;
-
-      public const byte GT = 11;
-      public const byte LT = 12;
-
-      public const byte AND = 13;
-      public const byte OR = 14;
-      public const byte NOT = 15;
-
-
-      public const byte Average = 16;
-
-      public const byte Call = 17;
-
-      public const byte Variable = 18;
-      public const byte LagVariable = 19;
-      public const byte Constant = 20;
-      public const byte Arg = 21;
-
-      public const byte Power = 22;
-      public const byte Root = 23;
-      public const byte TimeLag = 24;
-      public const byte Integral = 25;
-      public const byte Derivative = 26;
-
-      public const byte VariableCondition = 27;
-
-      public const byte Square = 28;
-      public const byte SquareRoot = 29;
-      public const byte Gamma = 30;
-      public const byte Psi = 31;
-      public const byte Dawson = 32;
-      public const byte ExponentialIntegralEi = 33;
-      public const byte CosineIntegral = 34;
-      public const byte SineIntegral = 35;
-      public const byte HyperbolicCosineIntegral = 36;
-      public const byte HyperbolicSineIntegral = 37;
-      public const byte FresnelCosineIntegral = 38;
-      public const byte FresnelSineIntegral = 39;
-      public const byte AiryA = 40;
-      public const byte AiryB = 41;
-      public const byte Norm = 42;
-      public const byte Erf = 43;
-      public const byte Bessel = 44;
-    }
-
-    #endregion
-
-    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>()
-                                                      {
-                                                        {typeof (Addition), OpCodes.Add},
-                                                        {typeof (Subtraction), OpCodes.Sub},
-                                                        {typeof (Multiplication), OpCodes.Mul},
-                                                        {typeof (Division), OpCodes.Div},
-                                                        {typeof (Sine), OpCodes.Sin},
-                                                        {typeof (Cosine), OpCodes.Cos},
-                                                        {typeof (Tangent), OpCodes.Tan},
-                                                        {typeof (Logarithm), OpCodes.Log},
-                                                        {typeof (Exponential), OpCodes.Exp},
-                                                        {typeof (IfThenElse), OpCodes.IfThenElse},
-                                                        {typeof (GreaterThan), OpCodes.GT},
-                                                        {typeof (LessThan), OpCodes.LT},
-                                                        {typeof (And), OpCodes.AND},
-                                                        {typeof (Or), OpCodes.OR},
-                                                        {typeof (Not), OpCodes.NOT},
-                                                        {typeof (Average), OpCodes.Average},
-                                                        {typeof (InvokeFunction), OpCodes.Call},
-                                                        {
-                                                          typeof (HeuristicLab.Problems.DataAnalysis.Symbolic.Variable),
-                                                          OpCodes.Variable
-                                                          },
-                                                        {typeof (LaggedVariable), OpCodes.LagVariable},
-                                                        {typeof (Constant), OpCodes.Constant},
-                                                        {typeof (Argument), OpCodes.Arg},
-                                                        {typeof (Power), OpCodes.Power},
-                                                        {typeof (Root), OpCodes.Root},
-                                                        {typeof (TimeLag), OpCodes.TimeLag},
-                                                        {typeof (Integral), OpCodes.Integral},
-                                                        {typeof (Derivative), OpCodes.Derivative},
-                                                        {typeof (VariableCondition), OpCodes.VariableCondition},
-                                                        {typeof (Square), OpCodes.Square},
-                                                        {typeof (SquareRoot), OpCodes.SquareRoot},
-                                                        {typeof (Gamma), OpCodes.Gamma},
-                                                        {typeof (Psi), OpCodes.Psi},
-                                                        {typeof (Dawson), OpCodes.Dawson},
-                                                        {typeof (ExponentialIntegralEi), OpCodes.ExponentialIntegralEi},
-                                                        {typeof (CosineIntegral), OpCodes.CosineIntegral},
-                                                        {typeof (SineIntegral), OpCodes.SineIntegral},
-                                                        {
-                                                          typeof (HyperbolicCosineIntegral),
-                                                          OpCodes.HyperbolicCosineIntegral
-                                                          },
-                                                        {
-                                                          typeof (HyperbolicSineIntegral), OpCodes.HyperbolicSineIntegral
-                                                          },
-                                                        {typeof (FresnelCosineIntegral), OpCodes.FresnelCosineIntegral},
-                                                        {typeof (FresnelSineIntegral), OpCodes.FresnelSineIntegral},
-                                                        {typeof (AiryA), OpCodes.AiryA},
-                                                        {typeof (AiryB), OpCodes.AiryB},
-                                                        {typeof (Norm), OpCodes.Norm},
-                                                        {typeof (Erf), OpCodes.Erf},
-                                                        {typeof (Bessel), OpCodes.Bessel}
-                                                      };
 
     public override bool CanChangeName {
@@ -254,13 +107,7 @@
 
     [StorableConstructor]
-    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(bool deserializing)
-      : base(deserializing) {
-    }
-
-    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(
-      SymbolicDataAnalysisExpressionTreeILEmittingInterpreter original, Cloner cloner)
-      : base(original, cloner) {
-    }
-
+    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(bool deserializing) : base(deserializing) { }
+
+    private SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicDataAnalysisExpressionTreeILEmittingInterpreter(this, cloner);
@@ -269,10 +116,6 @@
     public SymbolicDataAnalysisExpressionTreeILEmittingInterpreter()
       : base("SymbolicDataAnalysisExpressionTreeILEmittingInterpreter", "Interpreter for symbolic expression trees.") {
-      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName,
-                                                   "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.",
-                                                   new BoolValue(false)));
-      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName,
-                                                  "A counter for the total number of solutions the interpreter has evaluated",
-                                                  new IntValue(0)));
+      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     }
 
@@ -280,7 +123,5 @@
     private void AfterDeserialization() {
       if (!Parameters.ContainsKey(EvaluatedSolutionsParameterName))
-        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName,
-                                                    "A counter for the total number of solutions the interpreter has evaluated",
-                                                    new IntValue(0)));
+        Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
     }
 
@@ -297,36 +138,40 @@
     #endregion
 
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset,
-                                                               IEnumerable<int> rows) {
-      return GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows);
-    }
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows) {
-      return GetSymbolicExpressionTreeValues(tree, dataset, targetVariables, rows, 1);
-    }
-    // for each row for each horizon for each target variable one value
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows, int horizon) {
+    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
       if (CheckExpressionsWithIntervalArithmetic.Value)
-        throw new NotSupportedException(
-          "Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+
       EvaluatedSolutions.Value++; // increment the evaluated solutions counter
-      var compiler = new SymbolicExpressionTreeCompiler();
-      Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);
+      var state = PrepareInterpreterState(tree, dataset);
+
+      Type[] methodArgs = { typeof(int), typeof(IList<double>[]) };
+      DynamicMethod testFun = new DynamicMethod("TestFun", typeof(double), methodArgs, typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter).Module);
+
+      ILGenerator il = testFun.GetILGenerator();
+      CompileInstructions(il, state, dataset);
+      il.Emit(System.Reflection.Emit.OpCodes.Conv_R8);
+      il.Emit(System.Reflection.Emit.OpCodes.Ret);
+      var function = (CompiledFunction)testFun.CreateDelegate(typeof(CompiledFunction));
+
+      IList<double>[] columns = dataset.DoubleVariables.Select(v => dataset.GetReadOnlyDoubleValues(v)).ToArray();
+
+      foreach (var row in rows) {
+        yield return function(row, columns);
+      }
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      Dictionary<string, int> doubleVariableNames = dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
       int necessaryArgStackSize = 0;
-
-      Dictionary<string, int> doubleVariableNames =
-        dataset.DoubleVariables.Select((x, i) => new { x, i }).ToDictionary(e => e.x, e => e.i);
-
-      for (int i = 0; i < code.Length; i++) {
-        Instruction instr = code[i];
+      foreach (Instruction instr in code) {
         if (instr.opCode == OpCodes.Variable) {
-          var variableTreeNode = instr.dynamicNode as VariableTreeNode;
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
           instr.iArg0 = doubleVariableNames[variableTreeNode.VariableName];
-          code[i] = instr;
         } else if (instr.opCode == OpCodes.LagVariable) {
-          var variableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
-          instr.iArg0 = doubleVariableNames[variableTreeNode.VariableName];
-          code[i] = instr;
+          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = doubleVariableNames[laggedVariableTreeNode.VariableName];
         } else if (instr.opCode == OpCodes.VariableCondition) {
-          var variableConditionTreeNode = instr.dynamicNode as VariableConditionTreeNode;
+          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
           instr.iArg0 = doubleVariableNames[variableConditionTreeNode.VariableName];
         } else if (instr.opCode == OpCodes.Call) {
@@ -334,36 +179,5 @@
         }
       }
-      var state = new InterpreterState(code);
-      Type[] methodArgs = { typeof(int), typeof(IList<double>[]), typeof(IList<double>[]), typeof(int) };
-
-      CompiledFunction[] function = new CompiledFunction[targetVariables.Length];
-      for (int i = 0; i < function.Length; i++) {
-        DynamicMethod testFun = new DynamicMethod("TestFun", typeof(double), methodArgs, typeof(SymbolicDataAnalysisExpressionTreeILEmittingInterpreter).Module);
-        ILGenerator il = testFun.GetILGenerator();
-        CompileInstructions(il, state, dataset);
-        il.Emit(System.Reflection.Emit.OpCodes.Conv_R8);
-        il.Emit(System.Reflection.Emit.OpCodes.Ret);
-        function[i] = (CompiledFunction)testFun.CreateDelegate(typeof(CompiledFunction));
-      }
-      var values = doubleVariableNames.Keys
-        .Select(v => dataset.GetReadOnlyDoubleValues(v))
-        .ToArray();
-      var cachedValues = (from var in doubleVariableNames.Keys
-                          select new double[horizon]).ToArray();
-      foreach (var row in rows) {
-        // init first line of cache 
-        int c = 0;
-        foreach (var var in doubleVariableNames.Keys)
-          cachedValues[c++][0] = dataset.GetDoubleValue(var, row);
-        for (int horizonRow = row; horizonRow < row + horizon; horizonRow++) {
-          for (int i = 0; i < function.Length; i++) {
-            var componentProg = function[i](horizonRow, values, cachedValues, row);
-            // set cachedValues for prognosis of future values
-            if (horizon > 1)
-              cachedValues[doubleVariableNames[targetVariables[i]]][horizonRow - row] = componentProg;
-            yield return componentProg;
-          }
-        }
-      }
+      return new InterpreterState(code, necessaryArgStackSize);
     }
 
@@ -865,12 +679,4 @@
     }
 
-    private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
-      byte opCode;
-      if (!symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode))
-        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
-      return opCode;
-    }
-
-
     public static double AiryA(double x) {
       if (double.IsNaN(x)) return double.NaN;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 8435)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 8436)
@@ -22,5 +22,4 @@
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -33,180 +32,10 @@
   [StorableClass]
   [Item("SymbolicDataAnalysisExpressionTreeInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
-  public sealed class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem,
-    ISymbolicDataAnalysisExpressionTreeInterpreter, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
+  public class SymbolicDataAnalysisExpressionTreeInterpreter : ParameterizedNamedItem, ISymbolicDataAnalysisExpressionTreeInterpreter {
     private const string CheckExpressionsWithIntervalArithmeticParameterName = "CheckExpressionsWithIntervalArithmetic";
     private const string EvaluatedSolutionsParameterName = "EvaluatedSolutions";
-    #region private classes
-    private class InterpreterState {
-      private double[] argumentStack;
-      private int argumentStackPointer;
-      private Instruction[] code;
-      private int pc;
-      public int ProgramCounter {
-        get { return pc; }
-        set { pc = value; }
-      }
-      internal InterpreterState(Instruction[] code, int argumentStackSize) {
-        this.code = code;
-        this.pc = 0;
-        if (argumentStackSize > 0) {
-          this.argumentStack = new double[argumentStackSize];
-        }
-        this.argumentStackPointer = 0;
-      }
-
-      internal void Reset() {
-        this.pc = 0;
-        this.argumentStackPointer = 0;
-      }
-
-      internal Instruction NextInstruction() {
-        return code[pc++];
-      }
-      private void Push(double val) {
-        argumentStack[argumentStackPointer++] = val;
-      }
-      private double Pop() {
-        return argumentStack[--argumentStackPointer];
-      }
-
-      internal void CreateStackFrame(double[] argValues) {
-        // push in reverse order to make indexing easier
-        for (int i = argValues.Length - 1; i >= 0; i--) {
-          argumentStack[argumentStackPointer++] = argValues[i];
-        }
-        Push(argValues.Length);
-      }
-
-      internal void RemoveStackFrame() {
-        int size = (int)Pop();
-        argumentStackPointer -= size;
-      }
-
-      internal double GetStackFrameValue(ushort index) {
-        // layout of stack:
-        // [0]   <- argumentStackPointer
-        // [StackFrameSize = N + 1]
-        // [Arg0] <- argumentStackPointer - 2 - 0
-        // [Arg1] <- argumentStackPointer - 2 - 1
-        // [...]
-        // [ArgN] <- argumentStackPointer - 2 - N
-        // <Begin of stack frame>
-        return argumentStack[argumentStackPointer - index - 2];
-      }
-    }
-    private class OpCodes {
-      public const byte Add = 1;
-      public const byte Sub = 2;
-      public const byte Mul = 3;
-      public const byte Div = 4;
-
-      public const byte Sin = 5;
-      public const byte Cos = 6;
-      public const byte Tan = 7;
-
-      public const byte Log = 8;
-      public const byte Exp = 9;
-
-      public const byte IfThenElse = 10;
-
-      public const byte GT = 11;
-      public const byte LT = 12;
-
-      public const byte AND = 13;
-      public const byte OR = 14;
-      public const byte NOT = 15;
-
-
-      public const byte Average = 16;
-
-      public const byte Call = 17;
-
-      public const byte Variable = 18;
-      public const byte LagVariable = 19;
-      public const byte Constant = 20;
-      public const byte Arg = 21;
-
-      public const byte Power = 22;
-      public const byte Root = 23;
-      public const byte TimeLag = 24;
-      public const byte Integral = 25;
-      public const byte Derivative = 26;
-
-      public const byte VariableCondition = 27;
-
-      public const byte Square = 28;
-      public const byte SquareRoot = 29;
-      public const byte Gamma = 30;
-      public const byte Psi = 31;
-      public const byte Dawson = 32;
-      public const byte ExponentialIntegralEi = 33;
-      public const byte CosineIntegral = 34;
-      public const byte SineIntegral = 35;
-      public const byte HyperbolicCosineIntegral = 36;
-      public const byte HyperbolicSineIntegral = 37;
-      public const byte FresnelCosineIntegral = 38;
-      public const byte FresnelSineIntegral = 39;
-      public const byte AiryA = 40;
-      public const byte AiryB = 41;
-      public const byte Norm = 42;
-      public const byte Erf = 43;
-      public const byte Bessel = 44;
-    }
-    #endregion
-
-    private Dictionary<Type, byte> symbolToOpcode = new Dictionary<Type, byte>() {
-      { typeof(Addition), OpCodes.Add },
-      { typeof(Subtraction), OpCodes.Sub },
-      { typeof(Multiplication), OpCodes.Mul },
-      { typeof(Division), OpCodes.Div },
-      { typeof(Sine), OpCodes.Sin },
-      { typeof(Cosine), OpCodes.Cos },
-      { typeof(Tangent), OpCodes.Tan },
-      { typeof(Logarithm), OpCodes.Log },
-      { typeof(Exponential), OpCodes.Exp },
-      { typeof(IfThenElse), OpCodes.IfThenElse },
-      { typeof(GreaterThan), OpCodes.GT },
-      { typeof(LessThan), OpCodes.LT },
-      { typeof(And), OpCodes.AND },
-      { typeof(Or), OpCodes.OR },
-      { typeof(Not), OpCodes.NOT},
-      { typeof(Average), OpCodes.Average},
-      { typeof(InvokeFunction), OpCodes.Call },
-      { typeof(Variable), OpCodes.Variable },
-      { typeof(LaggedVariable), OpCodes.LagVariable },
-      { typeof(Constant), OpCodes.Constant },
-      { typeof(Argument), OpCodes.Arg },
-      { typeof(Power),OpCodes.Power},
-      { typeof(Root),OpCodes.Root},
-      { typeof(TimeLag), OpCodes.TimeLag}, 
-      { typeof(Integral), OpCodes.Integral},
-      { typeof(Derivative), OpCodes.Derivative},
-      { typeof(VariableCondition),OpCodes.VariableCondition},
-      { typeof(Square),OpCodes.Square},
-      { typeof(SquareRoot),OpCodes.SquareRoot},
-      { typeof(Gamma), OpCodes.Gamma },
-      { typeof(Psi), OpCodes.Psi },
-      { typeof(Dawson), OpCodes.Dawson},
-      { typeof(ExponentialIntegralEi), OpCodes.ExponentialIntegralEi },
-      { typeof(CosineIntegral), OpCodes.CosineIntegral },
-      { typeof(SineIntegral), OpCodes.SineIntegral },
-      { typeof(HyperbolicCosineIntegral), OpCodes.HyperbolicCosineIntegral },
-      { typeof(HyperbolicSineIntegral), OpCodes.HyperbolicSineIntegral },
-      { typeof(FresnelCosineIntegral), OpCodes.FresnelCosineIntegral },
-      { typeof(FresnelSineIntegral), OpCodes.FresnelSineIntegral },
-      { typeof(AiryA), OpCodes.AiryA },
-      { typeof(AiryB), OpCodes.AiryB },
-      { typeof(Norm), OpCodes.Norm},
-      { typeof(Erf), OpCodes.Erf},
-      { typeof(Bessel), OpCodes.Bessel}
-    };
-
-    public override bool CanChangeName {
-      get { return false; }
-    }
-    public override bool CanChangeDescription {
-      get { return false; }
-    }
+
+    public override bool CanChangeName { get { return false; } }
+    public override bool CanChangeDescription { get { return false; } }
 
     #region parameter properties
@@ -233,6 +62,6 @@
 
     [StorableConstructor]
-    private SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
-    private SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(SymbolicDataAnalysisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
     public override IDeepCloneable Clone(Cloner cloner) {
       return new SymbolicDataAnalysisExpressionTreeInterpreter(this, cloner);
@@ -245,4 +74,10 @@
     }
 
+    protected SymbolicDataAnalysisExpressionTreeInterpreter(string name, string description)
+      : base(name, description) {
+      Parameters.Add(new ValueParameter<BoolValue>(CheckExpressionsWithIntervalArithmeticParameterName, "Switch that determines if the interpreter checks the validity of expressions with interval arithmetic before evaluating the expression.", new BoolValue(false)));
+      Parameters.Add(new ValueParameter<IntValue>(EvaluatedSolutionsParameterName, "A counter for the total number of solutions the interpreter has evaluated", new IntValue(0)));
+    }
+
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
@@ -261,32 +96,29 @@
 
     public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows) {
-      return GetSymbolicExpressionTreeValues(tree, dataset, new string[] { "#NOTHING#" }, rows);
-    }
-
-    public IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, string[] targetVariables, IEnumerable<int> rows) {
-      return GetSymbolicExpressionTreeValues(tree, dataset, targetVariables, rows, 1);
-    }
-
-
-    // for each row for each horizon for each target variable one value 
-    public 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.");
+
       EvaluatedSolutions.Value++; // increment the evaluated solutions counter
-      var compiler = new SymbolicExpressionTreeCompiler();
-      Instruction[] code = compiler.Compile(tree, MapSymbolToOpCode);
+      var state = PrepareInterpreterState(tree, dataset);
+
+      foreach (var rowEnum in rows) {
+        int row = rowEnum;
+        yield return Evaluate(dataset, ref row, state);
+        state.Reset();
+      }
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
       int necessaryArgStackSize = 0;
-      for (int i = 0; i < code.Length; i++) {
-        Instruction instr = code[i];
+      foreach (Instruction instr in code) {
         if (instr.opCode == OpCodes.Variable) {
-          var variableTreeNode = instr.dynamicNode as VariableTreeNode;
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
           instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
-          code[i] = instr;
         } else if (instr.opCode == OpCodes.LagVariable) {
-          var laggedVariableTreeNode = instr.dynamicNode as LaggedVariableTreeNode;
+          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
           instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
-          code[i] = instr;
         } else if (instr.opCode == OpCodes.VariableCondition) {
-          var variableConditionTreeNode = instr.dynamicNode as VariableConditionTreeNode;
+          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
           instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
         } else if (instr.opCode == OpCodes.Call) {
@@ -294,40 +126,22 @@
         }
       }
-      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;
-        foreach (var horizonRow in Enumerable.Range(row, horizon)) {
-          int localRow = horizonRow; // create a local variable for the ref parameter
-          for (int c = 0; c < nComponents; c++) {
-            var prog = Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
-            yield return prog;
-            cachedPrognosedValues[targetVariables[c]][horizonRow - row] = prog;
-          }
-
-          state.Reset();
-        }
-      }
-    }
-
-    private double Evaluate(Dataset dataset, ref int row, int lastObservedRow, InterpreterState state, Dictionary<string, double[]> cachedPrognosedValues) {
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+
+
+    protected virtual double Evaluate(Dataset dataset, ref int row, InterpreterState state) {
       Instruction currentInstr = state.NextInstruction();
       switch (currentInstr.opCode) {
         case OpCodes.Add: {
-            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);
+            double s = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s += Evaluate(dataset, ref row, state);
             }
             return s;
           }
         case OpCodes.Sub: {
-            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);
+            double s = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              s -= Evaluate(dataset, ref row, state);
             }
             if (currentInstr.nArguments == 1) s = -s;
@@ -335,14 +149,14 @@
           }
         case OpCodes.Mul: {
-            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);
+            double p = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p *= Evaluate(dataset, ref row, state);
             }
             return p;
           }
         case OpCodes.Div: {
-            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);
+            double p = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              p /= Evaluate(dataset, ref row, state);
             }
             if (currentInstr.nArguments == 1) p = 1.0 / p;
@@ -350,48 +164,48 @@
           }
         case OpCodes.Average: {
-            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);
+            double sum = Evaluate(dataset, ref row, state);
+            for (int i = 1; i < currentInstr.nArguments; i++) {
+              sum += Evaluate(dataset, ref row, state);
             }
             return sum / currentInstr.nArguments;
           }
         case OpCodes.Cos: {
-            return Math.Cos(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Cos(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Sin: {
-            return Math.Sin(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Sin(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Tan: {
-            return Math.Tan(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Tan(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Square: {
-            return Math.Pow(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues), 2);
+            return Math.Pow(Evaluate(dataset, ref row, state), 2);
           }
         case OpCodes.Power: {
-            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
-            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            double x = Evaluate(dataset, ref row, state);
+            double y = Math.Round(Evaluate(dataset, ref row, state));
             return Math.Pow(x, y);
           }
         case OpCodes.SquareRoot: {
-            return Math.Sqrt(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Sqrt(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Root: {
-            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
-            double y = Math.Round(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            double x = Evaluate(dataset, ref row, state);
+            double y = Math.Round(Evaluate(dataset, ref row, state));
             return Math.Pow(x, 1 / y);
           }
         case OpCodes.Exp: {
-            return Math.Exp(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Exp(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Log: {
-            return Math.Log(Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues));
+            return Math.Log(Evaluate(dataset, ref row, state));
           }
         case OpCodes.Gamma: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else return alglib.gammafunction(x);
           }
         case OpCodes.Psi: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else if (x <= 0 && (Math.Floor(x) - x).IsAlmost(0)) return double.NaN;
@@ -399,10 +213,10 @@
           }
         case OpCodes.Dawson: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             return alglib.dawsonintegral(x);
           }
         case OpCodes.ExponentialIntegralEi: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             return alglib.exponentialintegralei(x);
@@ -410,5 +224,5 @@
         case OpCodes.SineIntegral: {
             double si, ci;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -419,5 +233,5 @@
         case OpCodes.CosineIntegral: {
             double si, ci;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -428,5 +242,5 @@
         case OpCodes.HyperbolicSineIntegral: {
             double shi, chi;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -437,5 +251,5 @@
         case OpCodes.HyperbolicCosineIntegral: {
             double shi, chi;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -446,5 +260,5 @@
         case OpCodes.FresnelCosineIntegral: {
             double c = 0, s = 0;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -455,5 +269,5 @@
         case OpCodes.FresnelSineIntegral: {
             double c = 0, s = 0;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -464,5 +278,5 @@
         case OpCodes.AiryA: {
             double ai, aip, bi, bip;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -473,5 +287,5 @@
         case OpCodes.AiryB: {
             double ai, aip, bi, bip;
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else {
@@ -481,34 +295,34 @@
           }
         case OpCodes.Norm: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else return alglib.normaldistribution(x);
           }
         case OpCodes.Erf: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else return alglib.errorfunction(x);
           }
         case OpCodes.Bessel: {
-            var x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            var x = Evaluate(dataset, ref row, state);
             if (double.IsNaN(x)) return double.NaN;
             else return alglib.besseli0(x);
           }
         case OpCodes.IfThenElse: {
-            double condition = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double condition = Evaluate(dataset, ref row, state);
             double result;
             if (condition > 0.0) {
-              result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); SkipInstructions(state);
+              result = Evaluate(dataset, ref row, state); state.SkipInstructions();
             } else {
-              SkipInstructions(state); result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+              state.SkipInstructions(); result = Evaluate(dataset, ref row, state);
             }
             return result;
           }
         case OpCodes.AND: {
-            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);
+            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);
               else {
-                SkipInstructions(state);
+                state.SkipInstructions();
               }
             }
@@ -516,9 +330,9 @@
           }
         case OpCodes.OR: {
-            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);
+            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);
               else {
-                SkipInstructions(state);
+                state.SkipInstructions();
               }
             }
@@ -526,15 +340,15 @@
           }
         case OpCodes.NOT: {
-            return Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues) > 0.0 ? -1.0 : 1.0;
+            return Evaluate(dataset, ref row, state) > 0.0 ? -1.0 : 1.0;
           }
         case OpCodes.GT: {
-            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
-            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double x = Evaluate(dataset, ref row, state);
+            double y = Evaluate(dataset, ref row, state);
             if (x > y) return 1.0;
             else return -1.0;
           }
         case OpCodes.LT: {
-            double x = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
-            double y = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double x = Evaluate(dataset, ref row, state);
+            double y = Evaluate(dataset, ref row, state);
             if (x < y) return 1.0;
             else return -1.0;
@@ -543,5 +357,5 @@
             var timeLagTreeNode = (LaggedTreeNode)currentInstr.dynamicNode;
             row += timeLagTreeNode.Lag;
-            double result = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double result = Evaluate(dataset, ref row, state);
             row -= timeLagTreeNode.Lag;
             return result;
@@ -553,9 +367,9 @@
             for (int i = 0; i < Math.Abs(timeLagTreeNode.Lag); i++) {
               row += Math.Sign(timeLagTreeNode.Lag);
-              sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+              sum += Evaluate(dataset, ref row, state);
               state.ProgramCounter = savedPc;
             }
             row -= timeLagTreeNode.Lag;
-            sum += Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            sum += Evaluate(dataset, ref row, state);
             return sum;
           }
@@ -567,11 +381,11 @@
         case OpCodes.Derivative: {
             int savedPc = state.ProgramCounter;
-            double f_0 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
+            double f_0 = Evaluate(dataset, ref row, state); row--;
             state.ProgramCounter = savedPc;
-            double f_1 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row -= 2;
+            double f_1 = Evaluate(dataset, ref row, state); row -= 2;
             state.ProgramCounter = savedPc;
-            double f_3 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues); row--;
+            double f_3 = Evaluate(dataset, ref row, state); row--;
             state.ProgramCounter = savedPc;
-            double f_4 = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double f_4 = Evaluate(dataset, ref row, state);
             row += 4;
 
@@ -582,5 +396,5 @@
             double[] argValues = new double[currentInstr.nArguments];
             for (int i = 0; i < currentInstr.nArguments; i++) {
-              argValues[i] = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+              argValues[i] = Evaluate(dataset, ref row, state);
             }
             // push on argument values on stack 
@@ -592,5 +406,5 @@
             state.ProgramCounter = (ushort)currentInstr.iArg0;
             // evaluate the function
-            double v = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double v = Evaluate(dataset, ref row, state);
 
             // delete the stack frame
@@ -608,6 +422,5 @@
               return double.NaN;
             var variableTreeNode = (VariableTreeNode)currentInstr.dynamicNode;
-            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;
+            return ((IList<double>)currentInstr.iArg0)[row] * variableTreeNode.Weight;
           }
         case OpCodes.LagVariable: {
@@ -616,9 +429,8 @@
             if (actualRow < 0 || actualRow >= dataset.Rows)
               return double.NaN;
-            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;
+            return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
           }
         case OpCodes.Constant: {
-            var constTreeNode = currentInstr.dynamicNode as ConstantTreeNode;
+            var constTreeNode = (ConstantTreeNode)currentInstr.dynamicNode;
             return constTreeNode.Value;
           }
@@ -630,15 +442,10 @@
               return double.NaN;
             var variableConditionTreeNode = (VariableConditionTreeNode)currentInstr.dynamicNode;
-            double variableValue;
-            if (row <= lastObservedRow || !cachedPrognosedValues.ContainsKey(variableConditionTreeNode.VariableName))
-              variableValue = ((IList<double>)currentInstr.iArg0)[row];
-            else
-              variableValue = cachedPrognosedValues[variableConditionTreeNode.VariableName][row - lastObservedRow - 1];
-
+            double variableValue = ((IList<double>)currentInstr.iArg0)[row];
             double x = variableValue - variableConditionTreeNode.Threshold;
             double p = 1 / (1 + Math.Exp(-variableConditionTreeNode.Slope * x));
 
-            double trueBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
-            double falseBranch = Evaluate(dataset, ref row, lastObservedRow, state, cachedPrognosedValues);
+            double trueBranch = Evaluate(dataset, ref row, state);
+            double falseBranch = Evaluate(dataset, ref row, state);
 
             return trueBranch * p + falseBranch * (1 - p);
@@ -647,20 +454,4 @@
       }
     }
-
-    private byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
-      byte opCode;
-      if (!symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode))
-        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
-      return opCode;
-    }
-
-    // skips a whole branch
-    private void SkipInstructions(InterpreterState state) {
-      int i = 1;
-      while (i > 0) {
-        i += state.NextInstruction().nArguments;
-        i--;
-      }
-    }
   }
 }
