Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/Compiler/SymbolicExpressionTreeCompiler.cs	(revision 7989)
@@ -25,14 +25,15 @@
 
 namespace HeuristicLab.Encodings.SymbolicExpressionTreeEncoding {
-  public class SymbolicExpressionTreeCompiler {
-    private Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
-    private List<Func<Instruction, Instruction>> postInstructionCompiledHooks = new List<Func<Instruction, Instruction>>();
+  public static class SymbolicExpressionTreeCompiler {
 
-    public Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+    public static Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+      return Compile(tree, opCodeMapper, Enumerable.Empty<Func<Instruction, Instruction>>());
+    }
+    public static Instruction[] Compile(ISymbolicExpressionTree tree, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) {
+      Dictionary<string, ushort> entryPoint = new Dictionary<string, ushort>();
       List<Instruction> code = new List<Instruction>();
-      entryPoint.Clear();
       // compile main body branches
       foreach (var branch in tree.Root.GetSubtree(0).Subtrees) {
-        code.AddRange(Compile(branch, opCodeMapper));
+        code.AddRange(Compile(branch, opCodeMapper, postInstructionCompiledHooks));
       }
       // compile function branches
@@ -43,5 +44,5 @@
         if (code.Count > ushort.MaxValue) throw new ArgumentException("Code for the tree is too long (> ushort.MaxValue).");
         entryPoint[branch.FunctionName] = (ushort)code.Count;
-        code.AddRange(Compile(branch.GetSubtree(0), opCodeMapper));
+        code.AddRange(Compile(branch.GetSubtree(0), opCodeMapper, postInstructionCompiledHooks));
       }
       // address of all functions is fixed now
@@ -59,5 +60,5 @@
     }
 
-    private IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper) {
+    private static IEnumerable<Instruction> Compile(ISymbolicExpressionTreeNode branch, Func<ISymbolicExpressionTreeNode, byte> opCodeMapper, IEnumerable<Func<Instruction, Instruction>> postInstructionCompiledHooks) {
       foreach (var node in branch.IterateNodesPrefix()) {
         Instruction instr = new Instruction();
@@ -77,13 +78,4 @@
       }
     }
-
-    /// <summary>
-    /// Adds a function that will be called every time an instruction is compiled.
-    /// The compiled will insert the instruction returned by the hook into the code.
-    /// </summary>
-    /// <param name="hook">The hook that should be called for each compiled instruction.</param>
-    public void AddInstructionPostProcessingHook(Func<Instruction, Instruction> hook) {
-      postInstructionCompiledHooks.Add(hook);
-    }
   }
 }
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views-3.4.csproj	(revision 7989)
@@ -103,4 +103,6 @@
     <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
     <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL" />
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/InteractiveSymbolicTimeSeriesPrognosisSolutionSimplifierView.cs	(revision 7989)
@@ -50,5 +50,5 @@
 
     protected override void UpdateModel(ISymbolicExpressionTree tree) {
-      var model = new SymbolicTimeSeriesPrognosisModel(tree, Content.Model.Interpreter, Content.ProblemData.TargetVariables.ToArray());
+      var model = new SymbolicTimeSeriesPrognosisModel(tree, Content.Model.Interpreter);
       SymbolicTimeSeriesPrognosisModel.Scale(model, Content.ProblemData);
       Content.Model = model;
@@ -66,35 +66,30 @@
     protected override Dictionary<ISymbolicExpressionTreeNode, double> CalculateImpactValues(ISymbolicExpressionTree tree) {
       var interpreter = Content.Model.Interpreter;
+      var rows = Content.ProblemData.TrainingIndizes;
       var dataset = Content.ProblemData.Dataset;
-      var rows = Content.ProblemData.TrainingIndizes;
-      Dictionary<ISymbolicExpressionTreeNode, double> impactValues =
-        new Dictionary<ISymbolicExpressionTreeNode, double>();
-      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Content.ProblemData.TargetVariables.ToArray(), rows, 1)
-        .ToArray();
-      int i = 0;
-      int nTargetVariables = Content.ProblemData.TargetVariables.Count();
-      foreach (var targetVariable in Content.ProblemData.TargetVariables) {
-        List<ISymbolicExpressionTreeNode> nodes = tree.Root.GetSubtree(0).GetSubtree(i).IterateNodesPostfix().ToList();
-        var targetValues = dataset.GetDoubleValues(targetVariable, rows);
-        OnlineCalculatorError errorState;
-        double originalR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalOutput.Skip(i).TakeEvery(nTargetVariables), out errorState);
-        if (errorState != OnlineCalculatorError.None) originalR2 = 0.0;
+      var targetVariable = Content.ProblemData.TargetVariable;
+      var targetValues = dataset.GetDoubleValues(targetVariable, rows);
+      var originalOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows).ToArray();
 
-        foreach (ISymbolicExpressionTreeNode node in nodes) {
-          var parent = node.Parent;
-          constantNode.Value = CalculateReplacementValue(node, tree);
-          ISymbolicExpressionTreeNode replacementNode = constantNode;
-          SwitchNode(parent, node, replacementNode);
-          var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, Content.ProblemData.TargetVariables.ToArray(), rows, 1);
-          double newR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, newOutput.Skip(i).TakeEvery(nTargetVariables), out errorState);
-          if (errorState != OnlineCalculatorError.None) newR2 = 0.0;
+      Dictionary<ISymbolicExpressionTreeNode, double> impactValues = new Dictionary<ISymbolicExpressionTreeNode, double>();
+      List<ISymbolicExpressionTreeNode> nodes = tree.Root.GetSubtree(0).GetSubtree(0).IterateNodesPostfix().ToList();
+      OnlineCalculatorError errorState;
+      double originalR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, originalOutput, out errorState);
+      if (errorState != OnlineCalculatorError.None) originalR2 = 0.0;
 
-          // impact = 0 if no change
-          // impact < 0 if new solution is better
-          // impact > 0 if new solution is worse
-          impactValues[node] = originalR2 - newR2;
-          SwitchNode(parent, replacementNode, node);
-        }
-        i++;
+      foreach (ISymbolicExpressionTreeNode node in nodes) {
+        var parent = node.Parent;
+        constantNode.Value = CalculateReplacementValue(node, tree);
+        ISymbolicExpressionTreeNode replacementNode = constantNode;
+        SwitchNode(parent, node, replacementNode);
+        var newOutput = interpreter.GetSymbolicExpressionTreeValues(tree, dataset, rows);
+        double newR2 = OnlinePearsonsRSquaredCalculator.Calculate(targetValues, newOutput, out errorState);
+        if (errorState != OnlineCalculatorError.None) newR2 = 0.0;
+
+        // impact = 0 if no change
+        // impact < 0 if new solution is better
+        // impact > 0 if new solution is worse
+        impactValues[node] = originalR2 - newR2;
+        SwitchNode(parent, replacementNode, node);
       }
       return impactValues;
@@ -113,5 +108,5 @@
       var interpreter = Content.Model.Interpreter;
       var rows = Content.ProblemData.TrainingIndizes;
-      var allPrognosedValues = interpreter.GetSymbolicExpressionTreeValues(tempTree, Content.ProblemData.Dataset, Content.ProblemData.TargetVariables.ToArray(), rows, 1);
+      var allPrognosedValues = interpreter.GetSymbolicExpressionTreeValues(tempTree, Content.ProblemData.Dataset, rows);
 
       return allPrognosedValues.Median();
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis-3.4.csproj	(revision 7989)
@@ -123,4 +123,5 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs" />
     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisInterpreterOperator.cs" />
     <Compile Include="Interfaces\ISymbolicTimeSeriesPrognosisEvaluator.cs" />
@@ -137,4 +138,5 @@
     <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs" />
     <Compile Include="SingleObjective\SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs" />
+    <Compile Include="SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs" />
     <Compile Include="SymbolicTimeSeriesPrognosisModel.cs" />
     <Compile Include="SymbolicTimeSeriesPrognosisSolution.cs" />
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7989)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/Interfaces/ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs	(revision 7989)
@@ -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.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
+  public interface ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter : ISymbolicDataAnalysisExpressionTreeInterpreter {
+    string TargetVariable { get; set; }
+    IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, int horizon);
+  }
+}
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator.cs	(revision 7989)
@@ -21,4 +21,6 @@
 
 
+using System;
+using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -27,7 +29,16 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [StorableClass]
   public abstract class SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator : SymbolicDataAnalysisSingleObjectiveEvaluator<ITimeSeriesPrognosisProblemData>, ISymbolicTimeSeriesPrognosisSingleObjectiveEvaluator {
     private const string HorizonParameterName = "Horizon";
+    private const string ApplyLinearScalingParameterName = "ApplyLinearScaling";
 
+    public IFixedValueParameter<BoolValue> ApplyLinearScalingParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters[ApplyLinearScalingParameterName]; }
+    }
+    public bool ApplyLinearScaling {
+      get { return ApplyLinearScalingParameter.Value.Value; }
+      set { ApplyLinearScalingParameter.Value.Value = value; }
+    }
     public IValueLookupParameter<IntValue> HorizonParameter {
       get { return (IValueLookupParameter<IntValue>)Parameters[HorizonParameterName]; }
@@ -42,5 +53,43 @@
     protected SymbolicTimeSeriesPrognosisSingleObjectiveEvaluator()
       : base() {
+      Parameters.Add(new FixedValueParameter<BoolValue>(ApplyLinearScalingParameterName, "Flag that indicates if the individual should be linearly scaled before evaluating.", new BoolValue(true)));
       Parameters.Add(new ValueLookupParameter<IntValue>(HorizonParameterName, "The time interval for which the prognosis should be calculated.", new IntValue(1)));
+      ApplyLinearScalingParameter.Hidden = true;
+    }
+
+
+    [ThreadStatic]
+    private static double[] cache;
+    protected static void CalculateWithScaling(IEnumerable<double> targetValues, IEnumerable<double> estimatedValues, IOnlineCalculator calculator, int maxRows) {
+      if (cache == null || cache.GetLength(0) < maxRows) {
+        cache = new double[maxRows];
+      }
+
+      //calculate linear scaling
+      //the static methods of the calculator could not be used as it performs a check if the enumerators have an equal amount of elements
+      //this is not true if the cache is used
+      int i = 0;
+      var linearScalingCalculator = new OnlineLinearScalingParameterCalculator();
+      var targetValuesEnumerator = targetValues.GetEnumerator();
+      var estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+      while (targetValuesEnumerator.MoveNext() && estimatedValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = estimatedValuesEnumerator.Current;
+        linearScalingCalculator.Add(estimated, target);
+        cache[i] = estimated;
+        i++;
+      }
+      double alpha = linearScalingCalculator.Alpha;
+      double beta = linearScalingCalculator.Beta;
+
+      //calculate the quality by using the passed online calculator
+      targetValuesEnumerator = targetValues.GetEnumerator();
+      i = 0;
+      while (targetValuesEnumerator.MoveNext()) {
+        double target = targetValuesEnumerator.Current;
+        double estimated = cache[i] * beta + alpha;
+        calculator.Add(target, estimated);
+        i++;
+      }
     }
   }
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator.cs	(revision 7989)
@@ -22,5 +22,4 @@
 using System;
 using System.Collections.Generic;
-using System.Drawing.Printing;
 using System.Linq;
 using HeuristicLab.Common;
@@ -51,9 +50,10 @@
       IEnumerable<int> rows = GenerateRowsToEvaluate();
 
-      double quality = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue,
-        solution,
+      var interpreter = (ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter)SymbolicDataAnalysisTreeInterpreterParameter.ActualValue;
+
+      double quality = Calculate(interpreter, solution,
         EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper,
         ProblemDataParameter.ActualValue,
-        rows, HorizonParameter.ActualValue.Value);
+        rows, HorizonParameter.ActualValue.Value, ApplyLinearScaling);
       QualityParameter.ActualValue = new DoubleValue(quality);
 
@@ -61,105 +61,23 @@
     }
 
-    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon) {
-      double[] alpha;
-      double[] beta;
-      DetermineScalingFactors(solution, problemData, interpreter, rows, out alpha, out beta);
-      var scaledSolution = Scale(solution, alpha, beta);
-      string[] targetVariables = problemData.TargetVariables.ToArray();
-      var meanSquaredErrorCalculators = Enumerable.Range(0, problemData.TargetVariables.Count())
-        .Select(i => new OnlineMeanSquaredErrorCalculator()).ToArray();
+    public static double Calculate(ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, ISymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows, int horizon, bool applyLinearScaling) {
+      IEnumerable<double> targetValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows.SelectMany(r => Enumerable.Range(r, horizon)));
+      IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, rows, horizon).SelectMany(x => x);
+      IEnumerable<double> boundedEstimatedValues = estimatedValues.LimitToRange(lowerEstimationLimit, upperEstimationLimit);
+      OnlineCalculatorError errorState;
 
-      var allContinuationsEnumerator = interpreter.GetSymbolicExpressionTreeValues(scaledSolution, problemData.Dataset,
-                                                                                  targetVariables,
-                                                                                  rows, horizon).GetEnumerator();
-      allContinuationsEnumerator.MoveNext();
-      // foreach row
-      foreach (var row in rows) {
-        // foreach horizon
-        for (int h = 0; h < horizon; h++) {
-          // foreach component
-          for (int i = 0; i < meanSquaredErrorCalculators.Length; i++) {
-            double e = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, allContinuationsEnumerator.Current));
-            meanSquaredErrorCalculators[i].Add(problemData.Dataset.GetDoubleValue(targetVariables[i], row + h), e);
-            if (meanSquaredErrorCalculators[i].ErrorState == OnlineCalculatorError.InvalidValueAdded)
-              return double.MaxValue;
-            allContinuationsEnumerator.MoveNext();
-          }
-        }
-      }
-      var meanCalculator = new OnlineMeanAndVarianceCalculator();
-      foreach (var calc in meanSquaredErrorCalculators) {
-        if (calc.ErrorState != OnlineCalculatorError.None) return double.MaxValue;
-        meanCalculator.Add(calc.MeanSquaredError);
-      }
+      double mse;
+      if (applyLinearScaling) {
+        var mseCalculator = new OnlineMeanSquaredErrorCalculator();
+        CalculateWithScaling(targetValues, boundedEstimatedValues, mseCalculator, problemData.Dataset.Rows);
+        errorState = mseCalculator.ErrorState;
+        mse = mseCalculator.MeanSquaredError;
+      } else
+        mse = OnlineMeanSquaredErrorCalculator.Calculate(targetValues, boundedEstimatedValues, out errorState);
 
-      return meanCalculator.MeanErrorState == OnlineCalculatorError.None ? meanCalculator.Mean : double.MaxValue;
+      if (errorState != OnlineCalculatorError.None) return Double.NaN;
+      else return mse;
     }
 
-    private static ISymbolicExpressionTree Scale(ISymbolicExpressionTree solution, double[] alpha, double[] beta) {
-      var clone = (ISymbolicExpressionTree)solution.Clone();
-      int n = alpha.Length;
-      for (int i = 0; i < n; i++) {
-        var parent = clone.Root.GetSubtree(0);
-        var rpb = clone.Root.GetSubtree(0).GetSubtree(i);
-        var scaledRpb = MakeSum(
-          MakeProduct(rpb,
-            MakeConstant(beta[i], clone.Root.Grammar), clone.Root.Grammar),
-            MakeConstant(alpha[i], clone.Root.Grammar), clone.Root.Grammar);
-        parent.RemoveSubtree(i);
-        parent.InsertSubtree(i, scaledRpb);
-      }
-      return clone;
-    }
-
-    private static ISymbolicExpressionTreeNode MakeSum(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeGrammar grammar) {
-      var sum = grammar.Symbols.Where(s => s is Addition).First().CreateTreeNode();
-      sum.AddSubtree(a);
-      sum.AddSubtree(b);
-      return sum;
-    }
-
-    private static ISymbolicExpressionTreeNode MakeProduct(ISymbolicExpressionTreeNode a, ISymbolicExpressionTreeNode b, ISymbolicExpressionTreeGrammar grammar) {
-      var prod = grammar.Symbols.Where(s => s is Multiplication).First().CreateTreeNode();
-      prod.AddSubtree(a);
-      prod.AddSubtree(b);
-      return prod;
-    }
-
-    private static ISymbolicExpressionTreeNode MakeConstant(double c, ISymbolicExpressionTreeGrammar grammar) {
-      var node = (ConstantTreeNode)grammar.Symbols.Where(s => s is Constant).First().CreateTreeNode();
-      node.Value = c;
-      return node;
-    }
-
-    private static void DetermineScalingFactors(ISymbolicExpressionTree solution, ITimeSeriesPrognosisProblemData problemData, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, IEnumerable<int> rows, out double[] alpha, out double[] beta) {
-      string[] targetVariables = problemData.TargetVariables.ToArray();
-      int nComponents = targetVariables.Length;
-      alpha = new double[nComponents];
-      beta = new double[nComponents];
-      var oneStepPredictionsEnumerator = interpreter.GetSymbolicExpressionTreeValues(solution, problemData.Dataset, targetVariables, rows).GetEnumerator();
-      var scalingParameterCalculators =
-        Enumerable.Repeat(0, nComponents).Select(x => new OnlineLinearScalingParameterCalculator()).ToArray();
-      var targetValues = problemData.Dataset.GetVectorEnumerable(targetVariables, rows);
-      var targetValueEnumerator = targetValues.GetEnumerator();
-
-      var more = oneStepPredictionsEnumerator.MoveNext() & targetValueEnumerator.MoveNext();
-      while (more) {
-        for (int i = 0; i < nComponents; i++) {
-          scalingParameterCalculators[i].Add(oneStepPredictionsEnumerator.Current, targetValueEnumerator.Current);
-          more = oneStepPredictionsEnumerator.MoveNext() & targetValueEnumerator.MoveNext();
-        }
-      }
-
-      for (int i = 0; i < nComponents; i++) {
-        if (scalingParameterCalculators[i].ErrorState == OnlineCalculatorError.None) {
-          alpha[i] = scalingParameterCalculators[i].Alpha;
-          beta[i] = scalingParameterCalculators[i].Beta;
-        } else {
-          alpha[i] = 0.0;
-          beta[i] = 1.0;
-        }
-      }
-    }
 
     public override double Evaluate(IExecutionContext context, ISymbolicExpressionTree tree, ITimeSeriesPrognosisProblemData problemData, IEnumerable<int> rows) {
@@ -168,5 +86,5 @@
       HorizonParameter.ExecutionContext = context;
 
-      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value);
+      double mse = Calculate(SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, tree, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper, problemData, rows, HorizonParameter.ActualValue.Value, ApplyLinearScaling);
 
       HorizonParameter.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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveProblem.cs	(revision 7989)
@@ -54,5 +54,4 @@
       : base(new TimeSeriesPrognosisProblemData(), new SymbolicTimeSeriesPrognosisSingleObjectiveMeanSquaredErrorEvaluator(), new SymbolicDataAnalysisExpressionTreeCreator()) {
       Parameters.Add(new FixedValueParameter<DoubleLimit>(EstimationLimitsParameterName, EstimationLimitsParameterDescription));
-
       EstimationLimitsParameter.Hidden = true;
 
@@ -61,6 +60,9 @@
       MaximumSymbolicExpressionTreeLength.Value = InitialMaximumTreeLength;
 
+      var interpeter = new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter();
+      interpeter.TargetVariable = ProblemData.TargetVariable;
+      SymbolicExpressionTreeInterpreter = interpeter;
+
       SymbolicExpressionTreeGrammarParameter.ValueChanged += (o, e) => ConfigureGrammarSymbols();
-
       ConfigureGrammarSymbols();
 
@@ -88,5 +90,10 @@
     protected override void OnProblemDataChanged() {
       base.OnProblemDataChanged();
+      var interpreter = SymbolicExpressionTreeInterpreter as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter;
+      if (interpreter != null) {
+        interpreter.TargetVariable = ProblemData.TargetVariable;
+      }
       UpdateEstimationLimits();
+
     }
 
@@ -107,5 +114,4 @@
       }
     }
-
   }
 }
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveTrainingBestSolutionAnalyzer.cs	(revision 7989)
@@ -20,5 +20,4 @@
 #endregion
 
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -76,5 +75,5 @@
 
     protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariables.ToArray(), EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScaling.Value)
         SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SingleObjective/SymbolicTimeSeriesPrognosisSingleObjectiveValidationBestSolutionAnalyzer.cs	(revision 7989)
@@ -20,5 +20,4 @@
 #endregion
 
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -65,5 +64,5 @@
 
     protected override ISymbolicTimeSeriesPrognosisSolution CreateSolution(ISymbolicExpressionTree bestTree, double bestQuality) {
-      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue, ProblemDataParameter.ActualValue.TargetVariables.ToArray(), EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
+      var model = new SymbolicTimeSeriesPrognosisModel((ISymbolicExpressionTree)bestTree.Clone(), SymbolicDataAnalysisTreeInterpreterParameter.ActualValue as ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, EstimationLimitsParameter.ActualValue.Lower, EstimationLimitsParameter.ActualValue.Upper);
       if (ApplyLinearScaling.Value)
         SymbolicTimeSeriesPrognosisModel.Scale(model, ProblemDataParameter.ActualValue);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs	(revision 7989)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisExpressionTreeInterpreter.cs	(revision 7989)
@@ -0,0 +1,136 @@
+﻿#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;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis {
+  [StorableClass]
+  [Item("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.")]
+  public sealed class SymbolicTimeSeriesPrognosisExpressionTreeInterpreter : SymbolicDataAnalysisExpressionTreeInterpreter, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter {
+    private const string TargetVariableParameterName = "TargetVariable";
+
+    public IFixedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IFixedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+      set { TargetVariableParameter.Value.Value = value; }
+    }
+
+    [ThreadStatic]
+    private static double[] targetVariableCache;
+    [ThreadStatic]
+    private static List<int> invalidateCacheIndexes;
+
+    [StorableConstructor]
+    private SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(bool deserializing) : base(deserializing) { }
+    private SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(SymbolicTimeSeriesPrognosisExpressionTreeInterpreter original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SymbolicTimeSeriesPrognosisExpressionTreeInterpreter(this, cloner);
+    }
+
+    public SymbolicTimeSeriesPrognosisExpressionTreeInterpreter()
+      : base("SymbolicTimeSeriesPrognosisInterpreter", "Interpreter for symbolic expression trees including automatically defined functions.") {
+      Parameters.Add(new FixedValueParameter<StringValue>(TargetVariableParameterName));
+      TargetVariableParameter.Hidden = true;
+    }
+
+    // for each row several (=#horizon) future predictions
+    public IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, int horizon) {
+      return GetSymbolicExpressionTreeValues(tree, dataset, rows, rows.Select(row => horizon));
+    }
+
+    public IEnumerable<IEnumerable<double>> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      if (CheckExpressionsWithIntervalArithmetic.Value)
+        throw new NotSupportedException("Interval arithmetic is not yet supported in the symbolic data analysis interpreter.");
+      if (targetVariableCache == null || targetVariableCache.GetLength(0) < dataset.Rows)
+        targetVariableCache = dataset.GetDoubleValues(TargetVariable).ToArray();
+      if (invalidateCacheIndexes == null)
+        invalidateCacheIndexes = new List<int>(10);
+
+      string targetVariable = TargetVariable;
+      EvaluatedSolutions.Value++; // increment the evaluated solutions counter
+      var state = PrepareInterpreterState(tree, dataset, targetVariableCache);
+      var rowsEnumerator = rows.GetEnumerator();
+      var horizonsEnumerator = horizons.GetEnumerator();
+
+      // produce a n-step forecast for all rows
+      while (rowsEnumerator.MoveNext() & horizonsEnumerator.MoveNext()) {
+        int row = rowsEnumerator.Current;
+        int horizon = horizonsEnumerator.Current;
+
+        double[] vProgs = new double[horizon];
+        for (int i = 0; i < horizon; i++) {
+          int localRow = i + row; // create a local variable for the ref parameter
+          vProgs[i] = Evaluate(dataset, ref localRow, state);
+          targetVariableCache[localRow] = vProgs[i];
+          invalidateCacheIndexes.Add(localRow);
+          state.Reset();
+        }
+
+        yield return vProgs;
+
+        int j = 0;
+        foreach (var targetValue in dataset.GetDoubleValues(TargetVariable, invalidateCacheIndexes)) {
+          targetVariableCache[invalidateCacheIndexes[j]] = targetValue;
+          j++;
+        }
+        invalidateCacheIndexes.Clear();
+      }
+
+      if (rowsEnumerator.MoveNext() || horizonsEnumerator.MoveNext())
+        throw new ArgumentException("Number of elements in rows and horizon enumerations doesn't match.");
+    }
+
+    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset, double[] targetVariableCache) {
+      Instruction[] code = SymbolicExpressionTreeCompiler.Compile(tree, OpCodes.MapSymbolToOpCode);
+      int necessaryArgStackSize = 0;
+      foreach (Instruction instr in code) {
+        if (instr.opCode == OpCodes.Variable) {
+          var variableTreeNode = (VariableTreeNode)instr.dynamicNode;
+          if (variableTreeNode.VariableName == TargetVariable)
+            instr.iArg0 = targetVariableCache;
+          else
+            instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.LagVariable) {
+          var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
+          instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.VariableCondition) {
+          var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
+          instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableConditionTreeNode.VariableName);
+        } else if (instr.opCode == OpCodes.Call) {
+          necessaryArgStackSize += instr.nArguments + 1;
+        }
+      }
+
+      return new InterpreterState(code, necessaryArgStackSize);
+    }
+  }
+}
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis/3.4/SymbolicTimeSeriesPrognosisModel.cs	(revision 7989)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Drawing;
@@ -64,8 +63,4 @@
     #endregion
 
-    [Storable]
-    private string[] targetVariables;
-
-
     [StorableConstructor]
     protected SymbolicTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
@@ -74,15 +69,13 @@
       this.symbolicExpressionTree = cloner.Clone(original.symbolicExpressionTree);
       this.interpreter = cloner.Clone(original.interpreter);
-      this.targetVariables = new string[original.targetVariables.Length];
-      Array.Copy(original.targetVariables, this.targetVariables, this.targetVariables.Length);
       this.lowerEstimationLimit = original.lowerEstimationLimit;
       this.upperEstimationLimit = original.upperEstimationLimit;
     }
-    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, IEnumerable<string> targetVariables, double lowerLimit = double.MinValue, double upperLimit = double.MaxValue)
+    public SymbolicTimeSeriesPrognosisModel(ISymbolicExpressionTree tree, ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter interpreter, double lowerLimit = double.MinValue, double upperLimit = double.MaxValue)
       : base() {
       this.name = ItemName;
       this.description = ItemDescription;
       this.symbolicExpressionTree = tree;
-      this.interpreter = interpreter; this.targetVariables = targetVariables.ToArray();
+      this.interpreter = interpreter;
       this.lowerEstimationLimit = lowerLimit;
       this.upperEstimationLimit = upperLimit;
@@ -93,20 +86,7 @@
     }
 
-    public IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon) {
-      var enumerator =
-        Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, targetVariables, rows, horizon).
-          GetEnumerator();
-      foreach (var r in rows) {
-        var l = new List<double[]>();
-        for (int h = 0; h < horizon; h++) {
-          double[] components = new double[targetVariables.Length];
-          for (int c = 0; c < components.Length; c++) {
-            enumerator.MoveNext();
-            components[c] = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, enumerator.Current));
-          }
-          l.Add(components);
-        }
-        yield return l;
-      }
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon) {
+      var estimatedValues = Interpreter.GetSymbolicExpressionTreeValues(SymbolicExpressionTree, dataset, rows, horizon);
+      return estimatedValues.Select(predictionPerRow => predictionPerRow.LimitToRange(lowerEstimationLimit, upperEstimationLimit));
     }
 
@@ -120,54 +100,39 @@
     public static void Scale(SymbolicTimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData) {
       var dataset = problemData.Dataset;
-      var targetVariables = problemData.TargetVariables.ToArray();
+      var targetVariable = problemData.TargetVariable;
       var rows = problemData.TrainingIndizes;
-      var estimatedValuesEnumerator = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset,
-                                                                              targetVariables,
-                                                                              rows).GetEnumerator();
-      var scalingParameterCalculators =
-        problemData.TargetVariables.Select(v => new OnlineLinearScalingParameterCalculator()).ToArray();
-      var targetValuesEnumerator = problemData.Dataset.GetVectorEnumerable(targetVariables, rows).GetEnumerator();
+      var estimatedValuesEnumerator = model.Interpreter.GetSymbolicExpressionTreeValues(model.SymbolicExpressionTree, dataset, rows);
+      var targetValuesEnumerator = problemData.Dataset.GetDoubleValues(targetVariable, rows);
 
-      var more = targetValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext();
-      // foreach row
-      while (more) {
-        // foreach component
-        for (int i = 0; i < targetVariables.Length; i++) {
-          scalingParameterCalculators[i].Add(estimatedValuesEnumerator.Current, targetValuesEnumerator.Current);
-          more = estimatedValuesEnumerator.MoveNext() & targetValuesEnumerator.MoveNext();
+      double alpha, beta;
+      OnlineCalculatorError error;
+      OnlineLinearScalingParameterCalculator.Calculate(estimatedValuesEnumerator, targetValuesEnumerator, out alpha, out beta, out error);
+      if (error != OnlineCalculatorError.None) return;
+
+      ConstantTreeNode alphaTreeNode = null;
+      ConstantTreeNode betaTreeNode = null;
+      // check if model has been scaled previously by analyzing the structure of the tree
+      var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
+      if (startNode.GetSubtree(0).Symbol is Addition) {
+        var addNode = startNode.GetSubtree(0);
+        if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication && addNode.GetSubtree(1).Symbol is Constant) {
+          alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
+          var mulNode = addNode.GetSubtree(0);
+          if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
+            betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
+          }
         }
       }
-
-      for (int i = 0; i < targetVariables.Count(); i++) {
-        if (scalingParameterCalculators[i].ErrorState != OnlineCalculatorError.None) continue;
-        double alpha = scalingParameterCalculators[i].Alpha;
-        double beta = scalingParameterCalculators[i].Beta;
-        ConstantTreeNode alphaTreeNode = null;
-        ConstantTreeNode betaTreeNode = null;
-        // check if model has been scaled previously by analyzing the structure of the tree
-        var startNode = model.SymbolicExpressionTree.Root.GetSubtree(0);
-        if (startNode.GetSubtree(i).Symbol is Addition) {
-          var addNode = startNode.GetSubtree(i);
-          if (addNode.SubtreeCount == 2 && addNode.GetSubtree(0).Symbol is Multiplication &&
-              addNode.GetSubtree(1).Symbol is Constant) {
-            alphaTreeNode = addNode.GetSubtree(1) as ConstantTreeNode;
-            var mulNode = addNode.GetSubtree(0);
-            if (mulNode.SubtreeCount == 2 && mulNode.GetSubtree(1).Symbol is Constant) {
-              betaTreeNode = mulNode.GetSubtree(1) as ConstantTreeNode;
-            }
-          }
-        }
-        // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
-        if (alphaTreeNode != null && betaTreeNode != null) {
-          betaTreeNode.Value *= beta;
-          alphaTreeNode.Value *= beta;
-          alphaTreeNode.Value += alpha;
-        } else {
-          var mainBranch = startNode.GetSubtree(i);
-          startNode.RemoveSubtree(i);
-          var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
-          startNode.InsertSubtree(i, scaledMainBranch);
-        }
-      } // foreach
+      // if tree structure matches the structure necessary for linear scaling then reuse the existing tree nodes
+      if (alphaTreeNode != null && betaTreeNode != null) {
+        betaTreeNode.Value *= beta;
+        alphaTreeNode.Value *= beta;
+        alphaTreeNode.Value += alpha;
+      } else {
+        var mainBranch = startNode.GetSubtree(0);
+        startNode.RemoveSubtree(0);
+        var scaledMainBranch = MakeSum(MakeProduct(mainBranch, beta), alpha);
+        startNode.AddSubtree(scaledMainBranch);
+      }
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Evaluators/SymbolicDataAnalysisEvaluator.cs	(revision 7989)
@@ -96,5 +96,5 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
-      if(!Parameters.ContainsKey(ValidRowIndicatorParameterName))
+      if (!Parameters.ContainsKey(ValidRowIndicatorParameterName))
         Parameters.Add(new ValueLookupParameter<StringValue>(ValidRowIndicatorParameterName, "An indicator variable in the data set that specifies which rows should be evaluated (those for which the indicator <> 0) (optional)."));
     }
@@ -104,6 +104,5 @@
     }
 
-    protected IEnumerable<int> GenerateRowsToEvaluate(double percentageOfRows)
-    {
+    protected IEnumerable<int> GenerateRowsToEvaluate(double percentageOfRows) {
 
       IEnumerable<int> rows;
@@ -112,5 +111,4 @@
       int testPartitionStart = ProblemDataParameter.ActualValue.TestPartition.Start;
       int testPartitionEnd = ProblemDataParameter.ActualValue.TestPartition.End;
-
       if (samplesEnd < samplesStart) throw new ArgumentException("Start value is larger than end value.");
 
@@ -125,11 +123,9 @@
 
       rows = rows.Where(i => i < testPartitionStart || testPartitionEnd <= i);
-      
-      if(ValidRowIndicatorParameter.ActualValue != null)
-      {
+      if (ValidRowIndicatorParameter.ActualValue != null) {
         string indicatorVar = ValidRowIndicatorParameter.ActualValue.Value;
         var problemData = ProblemDataParameter.ActualValue;
         var indicatorRow = problemData.Dataset.GetReadOnlyDoubleValues(indicatorVar);
-        rows = rows.Where(r=>!indicatorRow[r].IsAlmost(0.0));
+        rows = rows.Where(r => !indicatorRow[r].IsAlmost(0.0));
       }
       return rows;
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.csproj	(revision 7989)
@@ -150,5 +150,4 @@
     <Compile Include="Creators\SymbolicDataAnalysisExpressionRampedHalfAndHalfTreeCreator.cs" />
     <Compile Include="Creators\SymbolicDataAnalysisExpressionTreeCreator.cs" />
-    <Compile Include="Interfaces\ISymbolicTimeSeriesPrognogisExpressionTreeInterpreter.cs" />
     <Compile Include="Crossovers\MultiSymbolicDataAnalysisExpressionCrossover.cs" />
     <Compile Include="Crossovers\SymbolicDataAnalysisExpressionContextAwareCrossover.cs" />
@@ -178,5 +177,4 @@
     <Compile Include="Interfaces\ISymbolicDataAnalysisAnalyzer.cs" />
     <Compile Include="SymbolicDataAnalysisSingleObjectiveProblem.cs" />
-    <Compile Include="Interpreter\old_SymbolicDataAnalysisExpressionTreeInterpreter.cs" />
     <Compile Include="SymbolicDataAnalysisExpressionTreeSimplifier.cs" />
     <Compile Include="SymbolicDataAnalysisProblem.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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interfaces/ISymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7989)
@@ -26,5 +26,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  public interface ISymbolicDataAnalysisExpressionTreeInterpreter : ISymbolicTimeSeriesPrognosisExpressionTreeInterpreter, IStatefulItem {
+  public interface ISymbolicDataAnalysisExpressionTreeInterpreter : INamedItem, IStatefulItem {
     IEnumerable<double> GetSymbolicExpressionTreeValues(ISymbolicExpressionTree tree, Dataset dataset, IEnumerable<int> rows);
     IntValue EvaluatedSolutions { get; set; }
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/InterpreterState.cs	(revision 7989)
@@ -23,5 +23,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  internal class InterpreterState {
+  public class InterpreterState {
     private double[] argumentStack;
     private int argumentStackPointer;
@@ -32,5 +32,5 @@
       set { pc = value; }
     }
-    internal InterpreterState(Instruction[] code, int argumentStackSize) {
+    public InterpreterState(Instruction[] code, int argumentStackSize) {
       this.code = code;
       this.pc = 0;
@@ -41,14 +41,14 @@
     }
 
-    internal void Reset() {
+    public void Reset() {
       this.pc = 0;
       this.argumentStackPointer = 0;
     }
 
-    internal Instruction NextInstruction() {
+    public Instruction NextInstruction() {
       return code[pc++];
     }
     // skips a whole branch
-    internal void SkipInstructions() {
+    public void SkipInstructions() {
       int i = 1;
       while (i > 0) {
@@ -65,5 +65,5 @@
     }
 
-    internal void CreateStackFrame(double[] argValues) {
+    public void CreateStackFrame(double[] argValues) {
       // push in reverse order to make indexing easier
       for (int i = argValues.Length - 1; i >= 0; i--) {
@@ -73,10 +73,10 @@
     }
 
-    internal void RemoveStackFrame() {
+    public void RemoveStackFrame() {
       int size = (int)Pop();
       argumentStackPointer -= size;
     }
 
-    internal double GetStackFrameValue(ushort index) {
+    public double GetStackFrameValue(ushort index) {
       // layout of stack:
       // [0]   <- argumentStackPointer
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/OpCodes.cs	(revision 7989)
@@ -25,5 +25,5 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Symbolic {
-  internal static class OpCodes {
+  public static class OpCodes {
     public const byte Add = 1;
     public const byte Sub = 2;
@@ -132,8 +132,6 @@
     public static byte MapSymbolToOpCode(ISymbolicExpressionTreeNode treeNode) {
       byte opCode;
-      if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode))
-        return opCode;
-      else
-        throw new NotSupportedException("Symbol: " + treeNode.Symbol);
+      if (symbolToOpcode.TryGetValue(treeNode.Symbol.GetType(), out opCode)) return opCode;
+      else throw new NotSupportedException("Symbol: " + treeNode.Symbol);
     }
   }
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 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic/3.4/Interpreter/SymbolicDataAnalysisExpressionTreeInterpreter.cs	(revision 7989)
@@ -32,6 +32,5 @@
   [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";
@@ -67,6 +66,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);
@@ -79,4 +78,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() {
@@ -95,47 +100,27 @@
 
     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 state = PrepareInterpreterState(tree, dataset, targetVariables[0]);
-
-      // 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];
+      var state = PrepareInterpreterState(tree, dataset);
+
       foreach (var rowEnum in rows) {
         int row = rowEnum;
-        for (int localRow = row; localRow < row + horizon; localRow++) {
-          //int localRow = horizonRow; // create a local variable for the ref parameter
-          yield return Evaluate(dataset, ref localRow, row - 1, state, cachedPrognosedValues);
-          //cachedPrognosedValues[targetVariables[c]][horizonRow - row] = prog;
-          state.Reset();
-        }
+        yield return Evaluate(dataset, ref row, state);
+        state.Reset();
       }
     }
 
-    private InterpreterState PrepareInterpreterState(ISymbolicExpressionTree tree, Dataset dataset, string targetVariable) {
+    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 = (VariableTreeNode)instr.dynamicNode;
           instr.iArg0 = dataset.GetReadOnlyDoubleValues(variableTreeNode.VariableName);
-          code[i] = instr;
         } else if (instr.opCode == OpCodes.LagVariable) {
           var laggedVariableTreeNode = (LaggedVariableTreeNode)instr.dynamicNode;
           instr.iArg0 = dataset.GetReadOnlyDoubleValues(laggedVariableTreeNode.VariableName);
-          code[i] = instr;
         } else if (instr.opCode == OpCodes.VariableCondition) {
           var variableConditionTreeNode = (VariableConditionTreeNode)instr.dynamicNode;
@@ -148,18 +133,18 @@
     }
 
-    private double Evaluate(Dataset dataset, ref int row, int lastObservedRow, InterpreterState state, Dictionary<string, double[]> cachedPrognosedValues) {
+    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;
@@ -167,14 +152,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;
@@ -182,48 +167,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.IsAlmost(0.0)) return double.NaN;
@@ -232,10 +217,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);
@@ -243,5 +228,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 {
@@ -252,5 +237,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 {
@@ -261,5 +246,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 {
@@ -270,5 +255,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 {
@@ -279,5 +264,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 {
@@ -288,5 +273,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 {
@@ -297,5 +282,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 {
@@ -306,5 +291,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 {
@@ -314,32 +299,32 @@
           }
         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); state.SkipInstructions();
+              result = Evaluate(dataset, ref row, state); state.SkipInstructions();
             } else {
-              state.SkipInstructions(); 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 {
                 state.SkipInstructions();
@@ -349,7 +334,7 @@
           }
         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 {
                 state.SkipInstructions();
@@ -359,15 +344,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;
@@ -376,5 +361,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;
@@ -386,9 +371,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;
           }
@@ -400,11 +385,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;
 
@@ -415,5 +400,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 
@@ -425,5 +410,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
@@ -440,14 +425,11 @@
             if (row < 0 || row >= dataset.Rows) 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: {
             var laggedVariableTreeNode = (LaggedVariableTreeNode)currentInstr.dynamicNode;
             int actualRow = row + laggedVariableTreeNode.Lag;
-            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;
+            if (actualRow < 0 || actualRow >= dataset.Rows) return double.NaN;
+            return ((IList<double>)currentInstr.iArg0)[actualRow] * laggedVariableTreeNode.Weight;
           }
         case OpCodes.Constant: {
@@ -459,18 +441,13 @@
         //to determine the relative amounts of the true and false branch see http://en.wikipedia.org/wiki/Logistic_function
         case OpCodes.VariableCondition: {
-            if (row < 0 || row >= dataset.Rows)
-              return double.NaN;
+            if (row < 0 || row >= dataset.Rows) 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);
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 7989)
@@ -312,7 +312,5 @@
     </BootstrapperPackage>
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="obj\" />
-  </ItemGroup>
+  <ItemGroup />
   <ItemGroup>
     <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 7989)
@@ -22,10 +22,9 @@
 using System.Windows.Forms;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.MainForm;
 
 namespace HeuristicLab.Problems.DataAnalysis.Views {
   [View("TimeSeriesPrognosisnSolution View")]
-  [Content(typeof(TimeSeriesPrognosisSolutionBase), false)]
+  [Content(typeof(TimeSeriesPrognosisSolution), false)]
   public partial class TimeSeriesPrognosisSolutionView : DataAnalysisSolutionView {
     public TimeSeriesPrognosisSolutionView() {
@@ -33,6 +32,6 @@
     }
 
-    public new TimeSeriesPrognosisSolutionBase Content {
-      get { return (TimeSeriesPrognosisSolutionBase)base.Content; }
+    public new TimeSeriesPrognosisSolution Content {
+      get { return (TimeSeriesPrognosisSolution)base.Content; }
       set { base.Content = value; }
     }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionLineChartView.cs	(revision 7989)
@@ -58,20 +58,4 @@
     }
 
-    private void UpdateTargetVariables() {
-      // populate combobox
-      targetVariableComboBox.Items.Clear();
-      if (Content != null) {
-        if (testPrognosisStart < Content.ProblemData.TestPartition.Start || testPrognosisStart >= Content.ProblemData.TestPartition.End) {
-          testPrognosisStart = Content.ProblemData.TestPartition.Start;
-        }
-        foreach (var targetVariable in Content.ProblemData.TargetVariables)
-          targetVariableComboBox.Items.Add(targetVariable);
-
-        targetVariableComboBox.SelectedIndex = 0;
-      }
-    }
-
-
-
     private void RedrawChart() {
       this.chart.Series.Clear();
@@ -79,6 +63,5 @@
         this.chart.ChartAreas[0].AxisX.Minimum = 0;
         this.chart.ChartAreas[0].AxisX.Maximum = Content.ProblemData.Dataset.Rows - 1;
-        string targetVariable = (string)targetVariableComboBox.SelectedItem;
-        int varIndex = Content.ProblemData.TargetVariables.ToList().IndexOf(targetVariable);
+        string targetVariable = Content.ProblemData.TargetVariable;
 
         this.chart.Series.Add(TARGETVARIABLE_SERIES_NAME);
@@ -94,9 +77,9 @@
           this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TrainingIndizes.ToArray(),
-                        Content.PrognosedTrainingValues.SelectMany(x => x).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
+                        Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes.Take(1), Content.ProblemData.TrainingPartition.Size).SelectMany(x => x).ToArray());
         } else {
           this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TrainingIndizes.ToArray(),
-                        Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes, 1).SelectMany(x => x.Single()).Skip(varIndex).TakeEvery(Content.ProblemData.TargetVariables.Count()).ToArray());
+                        Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes, 1).SelectMany(x => x).ToArray());
         }
         this.chart.Series[PROGNOSEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
@@ -110,20 +93,11 @@
         this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.FastLine;
         if (prognosedValuesCheckbox.Checked) {
-          int offsetToStart = testPrognosisStart - Content.ProblemData.TestPartition.Start;
           this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Points
-            .DataBindXY(Content.ProblemData.TestIndizes.Skip(offsetToStart).ToArray(),
-                        Content.GetPrognosedValues(Enumerable.Range(testPrognosisStart, 1), Content.ProblemData.TestPartition.End - testPrognosisStart)
-                        .SelectMany(x => x.SelectMany(y => y))
-                        .Skip(varIndex)
-                        .TakeEvery(Content.ProblemData.TargetVariables.Count())
-                        .ToArray());
+            .DataBindXY(Content.ProblemData.TestIndizes.ToArray(),
+                        Content.GetPrognosedValues(Content.ProblemData.TestIndizes.Take(1), Content.ProblemData.TestPartition.Size).SelectMany(x => x).ToArray());
         } else {
           this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Points
             .DataBindXY(Content.ProblemData.TestIndizes.ToArray(),
-                        Content.GetPrognosedValues(Content.ProblemData.TestIndizes, 1)
-                        .SelectMany(x => x.Single())
-                        .Skip(varIndex)
-                        .TakeEvery(Content.ProblemData.TargetVariables.Count())
-                        .ToArray());
+                        Content.GetPrognosedValues(Content.ProblemData.TestIndizes, 1).SelectMany(x => x).ToArray());
         }
         this.chart.Series[PROGNOSEDVALUES_TEST_SERIES_NAME].Tag = Content;
@@ -159,9 +133,9 @@
     protected override void OnContentChanged() {
       base.OnContentChanged();
-      UpdateTargetVariables();
+      RedrawChart();
     }
 
     private void Content_ProblemDataChanged(object sender, EventArgs e) {
-      UpdateTargetVariables();
+      RedrawChart();
     }
     private void Content_ModelChanged(object sender, EventArgs e) {
@@ -212,7 +186,5 @@
               this.CreateAndAddStripLine("Training and Test", start, row, Color.FromArgb(40, Color.Green), Color.FromArgb(40, Color.Red), ChartHatchStyle.WideUpwardDiagonal);
               break;
-            default:
-              // should not happen
-              break;
+            default: throw new NotSupportedException();
           }
           curAttr = attr[row];
@@ -242,22 +214,18 @@
         }
       } else if (Content != null) {
-        string targetVariable = (string)targetVariableComboBox.SelectedItem;
-        int varIndex = Content.ProblemData.TargetVariables.ToList().IndexOf(targetVariable);
-
+        string targetVariable = Content.ProblemData.TargetVariable;
 
         IEnumerable<int> indizes = null;
         IEnumerable<double> predictedValues = null;
+
         switch (series.Name) {
           case PROGNOSEDVALUES_TRAINING_SERIES_NAME:
             indizes = Content.ProblemData.TrainingIndizes.ToArray();
-            predictedValues =
-              Content.PrognosedTrainingValues.SelectMany(x => x).Skip(varIndex).TakeEvery(
-                Content.ProblemData.TargetVariables.Count()).ToArray();
+            predictedValues = Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes.Take(1), Content.ProblemData.TrainingPartition.Size).First();
             break;
           case PROGNOSEDVALUES_TEST_SERIES_NAME:
             testPrognosisStart = Content.ProblemData.TestPartition.Start;
             indizes = Content.ProblemData.TestIndizes.ToArray();
-            predictedValues = Content.PrognosedTestValues.SelectMany(x => x).Skip(varIndex).TakeEvery(
-              Content.ProblemData.TargetVariables.Count()).ToArray();
+            predictedValues = Content.GetPrognosedValues(Content.ProblemData.TestIndizes.Take(1), Content.ProblemData.TestPartition.Size).First();
             break;
         }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionPrognosedValuesView.cs	(revision 7989)
@@ -82,57 +82,46 @@
 
     private void UpdateEstimatedValues() {
-      if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
-      else {
-        StringMatrix matrix = null;
-        List<string> columnNames = new List<string>();
-        if (Content != null) {
-          columnNames.Add("Id");
+      if (InvokeRequired) {
+        Invoke((Action)UpdateEstimatedValues);
+        return;
+      }
+      if (Content == null) return;
 
-          string[,] values = new string[Content.ProblemData.Dataset.Rows, 1 + 3 * Content.ProblemData.TargetVariables.Count()];
-          foreach (var row in Enumerable.Range(0, Content.ProblemData.Dataset.Rows))
-            values[row, 0] = row.ToString();
+      var targetVariable = Content.ProblemData.TargetVariable;
+      StringMatrix matrix = null;
+      List<string> columnNames = new List<string>();
+      columnNames.Add("Id");
 
-          var allPrognosedTraining = Content.PrognosedTrainingValues.SelectMany(x=>x).ToArray();
-          var allPrognosedTest = Content.PrognosedTestValues.SelectMany(x => x).ToArray();
-
-          int i = 0;
-          int targetVariableIndex = 0;
-          foreach (var targetVariable in Content.ProblemData.TargetVariables) {
-            var prognosedTraining =
-              allPrognosedTraining.Skip(targetVariableIndex).TakeEvery(Content.ProblemData.TargetVariables.Count());
-            var prognosedTest =
-              allPrognosedTest.Skip(targetVariableIndex).TakeEvery(Content.ProblemData.TargetVariables.Count());
-
-            double[] target = Content.ProblemData.Dataset.GetDoubleValues(targetVariable).ToArray();
-
-            var prognosedTrainingEnumerator = prognosedTraining.GetEnumerator();
-            foreach (var row in Content.ProblemData.TrainingIndizes) {
-              prognosedTrainingEnumerator.MoveNext();
-              values[row, i + 2] = prognosedTrainingEnumerator.Current.ToString();
-            }
-
-            var prognosedTestEnumerator = prognosedTest.GetEnumerator();
-            foreach (var row in Content.ProblemData.TestIndizes) {
-              prognosedTestEnumerator.MoveNext();
-              values[row, i + 3] = prognosedTestEnumerator.Current.ToString();
-            }
-
-            foreach (var row in Enumerable.Range(0, Content.ProblemData.Dataset.Rows)) {
-              values[row, i + 1] = target[row].ToString();
-            }
-
-            columnNames.AddRange(new string[] { targetVariable + "(actual)", targetVariable + "(training)", targetVariable + "(test)" });
-            i += 3;
-            targetVariableIndex++;
-          } // foreach
+      string[,] values = new string[Content.ProblemData.Dataset.Rows, 4];
+      var prognosedTraining = Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes.Take(1), Content.ProblemData.TrainingPartition.Size).First();
+      var prognosedTest = Content.GetPrognosedValues(Content.ProblemData.TrainingIndizes.Take(1), Content.ProblemData.TestPartition.Size).First();
+      double[] target = Content.ProblemData.Dataset.GetDoubleValues(targetVariable).ToArray();
 
 
-          matrix = new StringMatrix(values);
-          matrix.ColumnNames = columnNames.ToArray();
-          matrix.SortableView = true;
+      foreach (var row in Enumerable.Range(0, Content.ProblemData.Dataset.Rows)) {
+        values[row, 0] = row.ToString();
+        values[row, 1] = target[row].ToString();
+      }
 
-        } // if
-        matrixView.Content = matrix;
+      var rowsEnumerator = Content.ProblemData.TrainingIndizes.GetEnumerator();
+      var prognosisEnumerator = prognosedTraining.GetEnumerator();
+      while (rowsEnumerator.MoveNext() & prognosisEnumerator.MoveNext()) {
+        var row = rowsEnumerator.Current;
+        var prognosis = prognosisEnumerator.Current;
+        values[row, 2] = prognosis.ToString();
       }
+
+      rowsEnumerator = Content.ProblemData.TestIndizes.GetEnumerator();
+      prognosisEnumerator = prognosedTest.GetEnumerator();
+      while (rowsEnumerator.MoveNext() & prognosisEnumerator.MoveNext()) {
+        var row = rowsEnumerator.Current;
+        var prognosis = prognosisEnumerator.Current;
+        values[row, 3] = prognosis.ToString();
+      }
+
+      columnNames.AddRange(new string[] { targetVariable + "(actual)", targetVariable + "(training)", targetVariable + "(test)" });
+      matrix = new StringMatrix(values);
+      matrix.ColumnNames = columnNames.ToArray();
+      matrix.SortableView = true;
     }
     #endregion
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 7989)
@@ -193,6 +193,5 @@
       if (values == null) throw new ArgumentException("The varialbe " + variableName + " is not a double variable.");
 
-      foreach (int index in rows)
-        yield return values[index];
+      return rows.Select(index => values[index]);
     }
 
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 7989)
@@ -20,24 +20,8 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.PluginInfrastructure;
 
 namespace HeuristicLab.Problems.DataAnalysis {
   public static class DatasetExtensions {
-    public static IEnumerable<double> GetVectorEnumerable(this Dataset ds, IEnumerable<string> targetVariables, IEnumerable<int> rows) {
-      var vars = targetVariables.ToArray();
-      var values = (from var in vars
-                    select ds.GetReadOnlyDoubleValues(var))
-        .ToArray();
-
-      foreach (var r in rows) {
-        for (int i = 0; i < values.Length; i++)
-          yield return values[i][r];
-      }
-    }
-
     public static IEnumerable<T> TakeEvery<T>(this IEnumerable<T> xs, int nth) {
       int i = 0;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 7989)
@@ -33,5 +33,5 @@
   [Item("TimeSeriesPrognosisProblemData", "Represents an item containing all data defining a time series prognosis problem.")]
   public class TimeSeriesPrognosisProblemData : DataAnalysisProblemData, ITimeSeriesPrognosisProblemData {
-    protected const string TargetVariablesParameterName = "TargetVariables";
+    protected const string TargetVariableParameterName = "TargetVariable";
 
     #region default data
@@ -1540,5 +1540,5 @@
     private static readonly Dataset defaultDataset;
     private static readonly IEnumerable<string> defaultAllowedInputVariables;
-    private static readonly string[] defaultTargetVariables;
+    private static readonly string defaultTargetVariable;
 
     private static readonly TimeSeriesPrognosisProblemData emptyProblemData;
@@ -1551,5 +1551,5 @@
       defaultDataset.Name = "Mackey-Glass (t=17) Time Series Benchmark Dataset";
       defaultAllowedInputVariables = new List<string>() { "x" };
-      defaultTargetVariables = new string[] { "x" };
+      defaultTargetVariable = "x";
 
       var problemData = new TimeSeriesPrognosisProblemData();
@@ -1563,14 +1563,14 @@
       problemData.Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
       problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
-      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariablesParameterName, new ItemSet<StringValue>()));
+      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
       emptyProblemData = problemData;
     }
     #endregion
 
-    public ValueParameter<CheckedItemList<StringValue>> TargetVariablesParameter {
-      get { return (ValueParameter<CheckedItemList<StringValue>>)Parameters[TargetVariablesParameterName]; }
+    public ConstrainedValueParameter<StringValue> TargetVariableParameter {
+      get { return (ConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
     }
-    public IEnumerable<string> TargetVariables {
-      get { return TargetVariablesParameter.Value.CheckedItems.Select(x => x.Value.Value); }
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
     }
 
@@ -1592,22 +1592,17 @@
 
     public TimeSeriesPrognosisProblemData()
-      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariables) {
+      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
     }
 
-    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, IEnumerable<string> targetVariables)
+    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
       : base(dataset, allowedInputVariables) {
       var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
-      var targetVariablesList = new CheckedItemList<StringValue>(variables);
-      foreach (var targetVar in targetVariables) {
-        targetVariablesList.SetItemCheckedState(targetVariablesList.Single(x => x.Value == targetVar), true);
-      }
-      Parameters.Add(new FixedValueParameter<CheckedItemList<StringValue>>(TargetVariablesParameterName, targetVariablesList));
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.First(x => x.Value == targetVariable)));
       RegisterParameterEvents();
     }
 
     private void RegisterParameterEvents() {
-      TargetVariablesParameter.Value.CheckedItemsChanged += TargetVariableParameter_ValueChanged;
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
     }
-
     private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
       OnChanged();
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 7989)
@@ -21,5 +21,4 @@
 
 using System.Collections.Generic;
-using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -33,13 +32,7 @@
 
     [StorableConstructor]
-    protected TimeSeriesPrognosisSolution(bool deserializing)
-      : base(deserializing) {
-    }
-    protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    protected TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
-      : base(model, problemData) {
-    }
+    protected TimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner) : base(original, cloner) { }
+    protected TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData) : base(model, problemData) { }
 
     protected override void RecalculateResults() {
@@ -47,28 +40,6 @@
     }
 
-    public override IEnumerable<IEnumerable<double>> PrognosedTrainingValues {
-      get {
-        return GetPrognosedValues(ProblemData.TrainingIndizes.Take(1),
-          ProblemData.TrainingPartition.End - ProblemData.TrainingPartition.Start)
-          .First();
-      }
-    }
-    public override IEnumerable<IEnumerable<double>> PrognosedTestValues {
-      get {
-        return GetPrognosedValues(ProblemData.TestIndizes.Take(1),
-          ProblemData.TestPartition.End - ProblemData.TestPartition.Start)
-          .First();
-      }
-    }
-    public override IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(IEnumerable<int> rows, int horizon) {
+    public override IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, int horizon) {
       return Model.GetPrognosedValues(ProblemData.Dataset, rows, horizon);
-    }
-
-    protected override void OnProblemDataChanged() {
-      base.OnProblemDataChanged();
-    }
-
-    protected override void OnModelChanged() {
-      base.OnModelChanged();
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7989)
@@ -21,5 +21,4 @@
 
 using System;
-using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Linq;
@@ -75,88 +74,86 @@
     }
 
-    public abstract IEnumerable<IEnumerable<double>> PrognosedTrainingValues { get; }
-    public abstract IEnumerable<IEnumerable<double>> PrognosedTestValues { get; }
-    public abstract IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(IEnumerable<int> rows, int horizon);
+    public abstract IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, int horizon);
 
     #region Results
-    public double[] TrainingMeanSquaredError {
-      get { return ((DoubleArray)this[TrainingMeanSquaredErrorResultName].Value).ToArray(); }
-      private set { this[TrainingMeanSquaredErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestMeanSquaredError {
-      get { return ((DoubleArray)this[TestMeanSquaredErrorResultName].Value).ToArray(); }
-      private set { this[TestMeanSquaredErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingMeanAbsoluteError {
-      get { return ((DoubleArray)this[TrainingMeanAbsoluteErrorResultName].Value).ToArray(); }
-      private set { this[TrainingMeanAbsoluteErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestMeanAbsoluteError {
-      get { return ((DoubleArray)this[TestMeanAbsoluteErrorResultName].Value).ToArray(); }
-      private set { this[TestMeanAbsoluteErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingRSquared {
-      get { return ((DoubleArray)this[TrainingSquaredCorrelationResultName].Value).ToArray(); }
-      private set { this[TrainingSquaredCorrelationResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestRSquared {
-      get { return ((DoubleArray)this[TestSquaredCorrelationResultName].Value).ToArray(); }
-      private set { this[TestSquaredCorrelationResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingRelativeError {
-      get { return ((DoubleArray)this[TrainingRelativeErrorResultName].Value).ToArray(); }
-      private set { this[TrainingRelativeErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestRelativeError {
-      get { return ((DoubleArray)this[TestRelativeErrorResultName].Value).ToArray(); }
-      private set { this[TestRelativeErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingNormalizedMeanSquaredError {
-      get { return ((DoubleArray)this[TrainingNormalizedMeanSquaredErrorResultName].Value).ToArray(); }
-      private set { this[TrainingNormalizedMeanSquaredErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestNormalizedMeanSquaredError {
-      get { return ((DoubleArray)this[TestNormalizedMeanSquaredErrorResultName].Value).ToArray(); }
-      private set { this[TestNormalizedMeanSquaredErrorResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingDirectionalSymmetry {
-      get { return ((DoubleArray)this[TrainingDirectionalSymmetryResultName].Value).ToArray(); }
-      private set { this[TrainingDirectionalSymmetryResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestDirectionalSymmetry {
-      get { return ((DoubleArray)this[TestDirectionalSymmetryResultName].Value).ToArray(); }
-      private set { this[TestDirectionalSymmetryResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingWeightedDirectionalSymmetry {
-      get { return ((DoubleArray)this[TrainingWeightedDirectionalSymmetryResultName].Value).ToArray(); }
-      private set { this[TrainingWeightedDirectionalSymmetryResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestWeightedDirectionalSymmetry {
-      get { return ((DoubleArray)this[TestWeightedDirectionalSymmetryResultName].Value).ToArray(); }
-      private set { this[TestWeightedDirectionalSymmetryResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingTheilsUStatisticLast {
-      get { return ((DoubleArray)this[TrainingTheilsUStatisticLastResultName].Value).ToArray(); }
-      private set { this[TrainingTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestTheilsUStatisticLast {
-      get { return ((DoubleArray)this[TestTheilsUStatisticLastResultName].Value).ToArray(); }
-      private set { this[TestTheilsUStatisticLastResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingTheilsUStatisticMean {
-      get { return ((DoubleArray)this[TrainingTheilsUStatisticMeanResultName].Value).ToArray(); }
-      private set { this[TrainingTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestTheilsUStatisticMean {
-      get { return ((DoubleArray)this[TestTheilsUStatisticMeanResultName].Value).ToArray(); }
-      private set { this[TestTheilsUStatisticMeanResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TrainingTheilsUStatisticMovingAverage {
-      get { return ((DoubleArray)this[TrainingTheilsUStatisticMaResultName].Value).ToArray(); }
-      private set { this[TrainingTheilsUStatisticMaResultName].Value = new DoubleArray(value); }
-    }
-    public double[] TestTheilsUStatisticMovingAverage {
-      get { return ((DoubleArray)this[TestTheilsUStatisticMaResultName].Value).ToArray(); }
-      private set { this[TestTheilsUStatisticMaResultName].Value = new DoubleArray(value); }
+    public double TrainingMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanSquaredError {
+      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingMeanAbsoluteError {
+      get { return ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanAbsoluteError {
+      get { return ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value = value; }
+    }
+    public double TrainingRSquared {
+      get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
+    }
+    public double TestRSquared {
+      get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
+    }
+    public double TrainingRelativeError {
+      get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
+    }
+    public double TestRelativeError {
+      get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
+    }
+    public double TrainingNormalizedMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TestNormalizedMeanSquaredError {
+      get { return ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticLast {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticLastResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticLast {
+      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticMovingAverage {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticMaResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticMovingAverage {
+      get { return ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticMaResultName].Value).Value = value; }
     }
     #endregion
@@ -170,237 +167,145 @@
     protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
       : base(model, problemData) {
-      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleArray()));
-      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleArray()));
-      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new DoubleArray()));
-      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new DoubleArray()));
-      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleArray()));
-      Add(new Result(TrainingTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleArray()));
-      Add(new Result(TestTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleArray()));
+      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
+      Add(new Result(TestSquaredCorrelationResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
+      Add(new Result(TrainingRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the training partition", new DoubleValue()));
+      Add(new Result(TestRelativeErrorResultName, "Average of the relative errors of the model output and the actual values on the test partition", new DoubleValue()));
+      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestNormalizedMeanSquaredErrorResultName, "Normalized mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The average weighted directional symmetry of the forecasts of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleValue()));
       horizon = 1;
     }
 
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      if (horizon == 0) horizon = 1;
-      bool anyNewResult = false;
-      if (!ContainsKey(TrainingTheilsUStatisticLastResultName)) {
-        Add(new Result(TrainingTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the training partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (!ContainsKey(TestTheilsUStatisticLastResultName)) {
-        Add(new Result(TestTheilsUStatisticLastResultName, "The average Theil's U statistic (reference: previous value) of the forecasts of the model on the test partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (!ContainsKey(TrainingTheilsUStatisticMeanResultName)) {
-        Add(new Result(TrainingTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the training partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (!ContainsKey(TestTheilsUStatisticMeanResultName)) {
-        Add(new Result(TestTheilsUStatisticMeanResultName, "The average Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (!ContainsKey(TrainingTheilsUStatisticMaResultName)) {
-        Add(new Result(TrainingTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the training partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (!ContainsKey(TestTheilsUStatisticMaResultName)) {
-        Add(new Result(TestTheilsUStatisticMaResultName, "The average Theil's U statistic (reference: moving average) of the forecasts of the model on the test partition", new DoubleArray()));
-        anyNewResult = true;
-      }
-      if (anyNewResult)
-        RecalculateResults();
-    }
 
     protected void CalculateResults() {
-      string[] targetVariables = ProblemData.TargetVariables.ToArray();
-
-      var trainingMseCalculators = new OnlineMeanSquaredErrorCalculator[targetVariables.Length];
-      var testMseCalculators = new OnlineMeanSquaredErrorCalculator[targetVariables.Length];
-      var trainingMaeCalculators = new OnlineMeanAbsoluteErrorCalculator[targetVariables.Length];
-      var testMaeCalculators = new OnlineMeanAbsoluteErrorCalculator[targetVariables.Length];
-      var trainingRSquaredCalculators = new OnlinePearsonsRSquaredCalculator[targetVariables.Length];
-      var testRSquaredCalculators = new OnlinePearsonsRSquaredCalculator[targetVariables.Length];
-      var trainingRelErrorCalculators = new OnlineMeanAbsolutePercentageErrorCalculator[targetVariables.Length];
-      var testRelErrorCalculators = new OnlineMeanAbsolutePercentageErrorCalculator[targetVariables.Length];
-      var trainingNmseCalculators = new OnlineNormalizedMeanSquaredErrorCalculator[targetVariables.Length];
-      var testNmseCalculators = new OnlineNormalizedMeanSquaredErrorCalculator[targetVariables.Length];
-
-      var trainingDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
-      var testDsCalculators = new OnlineDirectionalSymmetryCalculator[targetVariables.Length];
-      var trainingWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
-      var testWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator[targetVariables.Length];
-      var trainingTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var testTheilsULastCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var trainingTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var testTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var trainingTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      var testTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator[targetVariables.Length];
-      for (int i = 0; i < targetVariables.Length; i++) {
-        trainingMseCalculators[i] = new OnlineMeanSquaredErrorCalculator();
-        testMseCalculators[i] = new OnlineMeanSquaredErrorCalculator();
-        trainingMaeCalculators[i] = new OnlineMeanAbsoluteErrorCalculator();
-        testMaeCalculators[i] = new OnlineMeanAbsoluteErrorCalculator();
-        trainingRSquaredCalculators[i] = new OnlinePearsonsRSquaredCalculator();
-        testRSquaredCalculators[i] = new OnlinePearsonsRSquaredCalculator();
-        trainingRelErrorCalculators[i] = new OnlineMeanAbsolutePercentageErrorCalculator();
-        testRelErrorCalculators[i] = new OnlineMeanAbsolutePercentageErrorCalculator();
-        trainingNmseCalculators[i] = new OnlineNormalizedMeanSquaredErrorCalculator();
-        testNmseCalculators[i] = new OnlineNormalizedMeanSquaredErrorCalculator();
-
-        trainingDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
-        testDsCalculators[i] = new OnlineDirectionalSymmetryCalculator();
-        trainingWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
-        testWdsCalculators[i] = new OnlineWeightedDirectionalSymmetryCalculator();
-        trainingTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        testTheilsULastCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        trainingTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        testTheilsUMeanCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        trainingTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
-        testTheilsUMovingAverageCalculators[i] = new OnlineTheilsUStatisticCalculator();
-      }
-
-      var allPrognosedTrainingValues = GetPrognosedValues(ProblemData.TrainingIndizes, horizon).GetEnumerator();
-      double[] mean = new double[targetVariables.Length];
-      for (int t = 0; t < targetVariables.Length; t++) {
-        double variance;
-        OnlineCalculatorError meanErrorState, varErrorState;
-        OnlineMeanAndVarianceCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(targetVariables[t], ProblemData.TrainingIndizes), out mean[t], out variance, out meanErrorState, out varErrorState);
-        if (meanErrorState != OnlineCalculatorError.None) mean[t] = 0.0;
-      }
+      string targetVariable = ProblemData.TargetVariable;
+
+      var trainingMseCalculators = new OnlineMeanSquaredErrorCalculator();
+      var testMseCalculators = new OnlineMeanSquaredErrorCalculator();
+      var trainingMaeCalculators = new OnlineMeanAbsoluteErrorCalculator();
+      var testMaeCalculators = new OnlineMeanAbsoluteErrorCalculator();
+      var trainingRSquaredCalculators = new OnlinePearsonsRSquaredCalculator();
+      var testRSquaredCalculators = new OnlinePearsonsRSquaredCalculator();
+      var trainingRelErrorCalculators = new OnlineMeanAbsolutePercentageErrorCalculator();
+      var testRelErrorCalculators = new OnlineMeanAbsolutePercentageErrorCalculator();
+      var trainingNmseCalculators = new OnlineNormalizedMeanSquaredErrorCalculator();
+      var testNmseCalculators = new OnlineNormalizedMeanSquaredErrorCalculator();
+
+      var trainingDsCalculators = new OnlineDirectionalSymmetryCalculator();
+      var testDsCalculators = new OnlineDirectionalSymmetryCalculator();
+      var trainingWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator();
+      var testWdsCalculators = new OnlineWeightedDirectionalSymmetryCalculator();
+      var trainingTheilsULastCalculators = new OnlineTheilsUStatisticCalculator();
+      var testTheilsULastCalculators = new OnlineTheilsUStatisticCalculator();
+      var trainingTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator();
+      var testTheilsUMeanCalculators = new OnlineTheilsUStatisticCalculator();
+      var trainingTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator();
+      var testTheilsUMovingAverageCalculators = new OnlineTheilsUStatisticCalculator();
+
+      double mean = ProblemData.Dataset.GetDoubleValues(targetVariable, ProblemData.TrainingIndizes).Average();
+
       foreach (var row in ProblemData.TrainingIndizes) {
         if (row + horizon < ProblemData.Dataset.Rows) {
-          allPrognosedTrainingValues.MoveNext();
-          var prognosedTrainingValues = allPrognosedTrainingValues.Current.SelectMany(x => x.ToArray()).ToArray();
-          for (int t = 0; t < targetVariables.Length; t++) {
-            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
-                                                                         Enumerable.Range(row, horizon));
-            int maWindow = 10 * horizon;
-            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
-                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
-                                                    where r > 0
-                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
-                                                   ).Average();
-            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
-            var prognosedContinuation = prognosedTrainingValues.Skip(t).TakeEvery(targetVariables.Length);
-            trainingDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            trainingWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            trainingTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            trainingTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean[t]), actualContinuation, prognosedContinuation);
-            trainingTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
-
-            var actualContinuationEnumerator = actualContinuation.GetEnumerator();
-            var prognosedContinuationEnumerator = prognosedContinuation.GetEnumerator();
-            while (actualContinuationEnumerator.MoveNext() & prognosedContinuationEnumerator.MoveNext()) {
-              trainingMseCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              trainingMaeCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              trainingRelErrorCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              trainingRSquaredCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              trainingNmseCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-            }
-            if (actualContinuationEnumerator.MoveNext() | prognosedContinuationEnumerator.MoveNext())
-              throw new ArgumentException(
-                "Different number of elements in Actual continuation and prognosed continuation.");
+          var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(row, horizon)).ToList();
+          var prognosedContinuation = GetPrognosedValues(new List<int> { row }, horizon).First().ToList();
+
+          int maWindow = 10 * horizon;
+          var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
+                                          select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
+                                                  where r > 0
+                                                  select ProblemData.Dataset.GetDoubleValue(targetVariable, r)
+                                                 ).Average();
+
+          double startValue = ProblemData.Dataset.GetDoubleValue(targetVariable, row - 1);
+
+          trainingDsCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          trainingWdsCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          trainingTheilsULastCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          trainingTheilsUMeanCalculators.Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
+          trainingTheilsUMovingAverageCalculators.Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
+
+          var actualContinuationEnumerator = actualContinuation.GetEnumerator();
+          var prognosedContinuationEnumerator = prognosedContinuation.GetEnumerator();
+
+          while (actualContinuationEnumerator.MoveNext() & prognosedContinuationEnumerator.MoveNext()) {
+            trainingMseCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            trainingMaeCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            trainingRelErrorCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            trainingRSquaredCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            trainingNmseCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
           }
+          if (actualContinuationEnumerator.MoveNext() | prognosedContinuationEnumerator.MoveNext())
+            throw new ArgumentException("Different number of elements in Actual continuation and prognosed continuation.");
         }
       }
-      var allPrognosedTestValues = GetPrognosedValues(ProblemData.TestIndizes, horizon).ToArray().AsEnumerable().GetEnumerator();
+
+      mean = ProblemData.Dataset.GetDoubleValues(targetVariable, ProblemData.TestIndizes).Average();
       foreach (var row in ProblemData.TestIndizes) {
         if (row + horizon < ProblemData.Dataset.Rows) {
-          allPrognosedTestValues.MoveNext();
-          var prognosedTestValues = allPrognosedTestValues.Current.SelectMany(x => x);
-          for (int t = 0; t < targetVariables.Length; t++) {
-            var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariables[t],
-                                                                         Enumerable.Range(row, horizon));
-            int maWindow = 10 * horizon;
-            var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
-                                            select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
-                                                    where r > 0
-                                                    select ProblemData.Dataset.GetDoubleValue(targetVariables[t], r)
-                                                   ).Average();
-            double startValue = ProblemData.Dataset.GetDoubleValue(targetVariables[t], row - 1);
-            var prognosedContinuation = prognosedTestValues.Skip(t).TakeEvery(targetVariables.Length).ToArray();
-            testDsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            testWdsCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            testTheilsULastCalculators[t].Add(startValue, actualContinuation, prognosedContinuation);
-            testTheilsUMeanCalculators[t].Add(startValue, actualContinuation.Select(x => mean[t]), actualContinuation, prognosedContinuation);
-            testTheilsUMovingAverageCalculators[t].Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
-
-            var actualContinuationEnumerator = actualContinuation.GetEnumerator();
-            var prognosedContinuationEnumerator = prognosedContinuation.AsEnumerable().GetEnumerator();
-            while (actualContinuationEnumerator.MoveNext() & prognosedContinuationEnumerator.MoveNext()) {
-              testMseCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              testMaeCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              testRelErrorCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              testRSquaredCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-              testNmseCalculators[t].Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
-            }
-            if (actualContinuationEnumerator.MoveNext() | prognosedContinuationEnumerator.MoveNext())
-              throw new ArgumentException(
-                "Different number of elements in Actual continuation and prognosed continuation.");
+          var actualContinuation = ProblemData.Dataset.GetDoubleValues(targetVariable, Enumerable.Range(row, horizon)).ToList();
+          var prognosedContinuation = GetPrognosedValues(new List<int> { row }, horizon).First().ToList();
+
+          int maWindow = 10 * horizon;
+          var movingAverageContinuation = from h in Enumerable.Range(0, horizon)
+                                          select (from r in Enumerable.Range(row + h - maWindow, maWindow - h)
+                                                  where r > 0
+                                                  select ProblemData.Dataset.GetDoubleValue(targetVariable, r)
+                                                 ).Average();
+
+          double startValue = ProblemData.Dataset.GetDoubleValue(targetVariable, row - 1);
+          testDsCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          testWdsCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          testTheilsULastCalculators.Add(startValue, actualContinuation, prognosedContinuation);
+          testTheilsUMeanCalculators.Add(startValue, actualContinuation.Select(x => mean), actualContinuation, prognosedContinuation);
+          testTheilsUMovingAverageCalculators.Add(startValue, movingAverageContinuation, actualContinuation, prognosedContinuation);
+
+          var actualContinuationEnumerator = actualContinuation.GetEnumerator();
+          var prognosedContinuationEnumerator = prognosedContinuation.GetEnumerator();
+          while (actualContinuationEnumerator.MoveNext() & prognosedContinuationEnumerator.MoveNext()) {
+            testMseCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            testMaeCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            testRelErrorCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            testRSquaredCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
+            testNmseCalculators.Add(actualContinuationEnumerator.Current, prognosedContinuationEnumerator.Current);
           }
+          if (actualContinuationEnumerator.MoveNext() | prognosedContinuationEnumerator.MoveNext())
+            throw new ArgumentException("Different number of elements in Actual continuation and prognosed continuation.");
         }
       }
 
-
-      TrainingMeanSquaredError = trainingMseCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestMeanSquaredError = testMseCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingMeanAbsoluteError = trainingMaeCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestMeanAbsoluteError = testMaeCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingRelativeError = trainingRelErrorCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestRelativeError = testRelErrorCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingRSquared = trainingRSquaredCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
-        .ToArray();
-      TestRSquared = testRSquaredCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
-        .ToArray();
-      TrainingNormalizedMeanSquaredError = trainingNmseCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestNormalizedMeanSquaredError = testNmseCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-
-      TrainingDirectionalSymmetry = trainingDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
-        .ToArray();
-      TestDirectionalSymmetry = testDsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : 0.0)
-        .ToArray();
-      TrainingWeightedDirectionalSymmetry = trainingWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestWeightedDirectionalSymmetry = testWdsCalculators.Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingTheilsUStatisticLast = trainingTheilsULastCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestTheilsUStatisticLast = testTheilsULastCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingTheilsUStatisticMean = trainingTheilsUMeanCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestTheilsUStatisticMean = testTheilsUMeanCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TrainingTheilsUStatisticMovingAverage = trainingTheilsUMovingAverageCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
-      TestTheilsUStatisticMovingAverage = testTheilsUMovingAverageCalculators
-        .Select(c => c.ErrorState == OnlineCalculatorError.None ? c.Value : double.PositiveInfinity)
-        .ToArray();
+      TrainingMeanSquaredError = trainingMseCalculators.ErrorState == OnlineCalculatorError.None ? trainingMseCalculators.Value : double.PositiveInfinity;
+      TestMeanSquaredError = testMseCalculators.ErrorState == OnlineCalculatorError.None ? testMseCalculators.Value : double.PositiveInfinity;
+      TrainingMeanAbsoluteError = trainingMaeCalculators.ErrorState == OnlineCalculatorError.None ? trainingMaeCalculators.Value : double.PositiveInfinity;
+      TestMeanAbsoluteError = testMaeCalculators.ErrorState == OnlineCalculatorError.None ? testMaeCalculators.Value : double.PositiveInfinity;
+      TrainingRelativeError = trainingRelErrorCalculators.ErrorState == OnlineCalculatorError.None ? trainingRelErrorCalculators.Value : double.PositiveInfinity;
+      TestRelativeError = testRelErrorCalculators.ErrorState == OnlineCalculatorError.None ? testRelErrorCalculators.Value : double.PositiveInfinity;
+      TrainingRSquared = trainingRSquaredCalculators.ErrorState == OnlineCalculatorError.None ? trainingRSquaredCalculators.Value : 0.0;
+      TestRSquared = testRSquaredCalculators.ErrorState == OnlineCalculatorError.None ? testRSquaredCalculators.Value : 0.0;
+      TrainingNormalizedMeanSquaredError = trainingNmseCalculators.ErrorState == OnlineCalculatorError.None ? trainingNmseCalculators.Value : double.PositiveInfinity;
+      TestNormalizedMeanSquaredError = testNmseCalculators.ErrorState == OnlineCalculatorError.None ? testNmseCalculators.Value : double.PositiveInfinity;
+
+      TrainingDirectionalSymmetry = trainingDsCalculators.ErrorState == OnlineCalculatorError.None ? trainingDsCalculators.Value : 0.0;
+      TestDirectionalSymmetry = testDsCalculators.ErrorState == OnlineCalculatorError.None ? testDsCalculators.Value : 0.0;
+      TrainingWeightedDirectionalSymmetry = trainingWdsCalculators.ErrorState == OnlineCalculatorError.None ? trainingWdsCalculators.Value : double.PositiveInfinity;
+      TestWeightedDirectionalSymmetry = testWdsCalculators.ErrorState == OnlineCalculatorError.None ? testWdsCalculators.Value : double.PositiveInfinity;
+      TrainingTheilsUStatisticLast = trainingTheilsULastCalculators.ErrorState == OnlineCalculatorError.None ? trainingTheilsULastCalculators.Value : double.PositiveInfinity;
+      TestTheilsUStatisticLast = testTheilsULastCalculators.ErrorState == OnlineCalculatorError.None ? testTheilsULastCalculators.Value : double.PositiveInfinity;
+      TrainingTheilsUStatisticMean = trainingTheilsUMeanCalculators.ErrorState == OnlineCalculatorError.None ? trainingTheilsUMeanCalculators.Value : double.PositiveInfinity;
+      TestTheilsUStatisticMean = testTheilsUMeanCalculators.ErrorState == OnlineCalculatorError.None ? testTheilsUMeanCalculators.Value : double.PositiveInfinity;
+      TrainingTheilsUStatisticMovingAverage = trainingTheilsUMovingAverageCalculators.ErrorState == OnlineCalculatorError.None ? trainingTheilsUMovingAverageCalculators.Value : double.PositiveInfinity;
+      TestTheilsUStatisticMovingAverage = testTheilsUMovingAverageCalculators.ErrorState == OnlineCalculatorError.None ? testTheilsUMovingAverageCalculators.Value : double.PositiveInfinity;
     }
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 7989)
@@ -23,5 +23,5 @@
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface ITimeSeriesPrognosisModel : IDataAnalysisModel {
-    IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon);
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, int horizon);
     ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData);
   }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 7989)
@@ -20,8 +20,7 @@
 #endregion
 
-using System.Collections.Generic;
 namespace HeuristicLab.Problems.DataAnalysis {
   public interface ITimeSeriesPrognosisProblemData : IDataAnalysisProblemData {
-    IEnumerable<string> TargetVariables { get; }
+    string TargetVariable { get; }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 7989)
@@ -27,26 +27,24 @@
     new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
 
-    IEnumerable<IEnumerable<double>> PrognosedTrainingValues { get; }
-    IEnumerable<IEnumerable<double>> PrognosedTestValues { get; }
-    IEnumerable<IEnumerable<IEnumerable<double>>> GetPrognosedValues(IEnumerable<int> rows, int horizon);
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, int horizon);
 
-    double[] TrainingMeanSquaredError { get; }
-    double[] TestMeanSquaredError { get; }
-    double[] TrainingMeanAbsoluteError { get; }
-    double[] TestMeanAbsoluteError { get; }
-    double[] TrainingRSquared { get; }
-    double[] TestRSquared { get; }
-    double[] TrainingRelativeError { get; }
-    double[] TestRelativeError { get; }
-    double[] TrainingNormalizedMeanSquaredError { get; }
-    double[] TestNormalizedMeanSquaredError { get; }
-    double[] TrainingTheilsUStatisticLast { get; }
-    double[] TestTheilsUStatisticLast { get; }
-    double[] TrainingTheilsUStatisticMean { get; }
-    double[] TestTheilsUStatisticMean { get; }
-    double[] TrainingDirectionalSymmetry { get; }
-    double[] TestDirectionalSymmetry { get; }
-    double[] TrainingWeightedDirectionalSymmetry { get; }
-    double[] TestWeightedDirectionalSymmetry { get; }
+    double TrainingMeanSquaredError { get; }
+    double TestMeanSquaredError { get; }
+    double TrainingMeanAbsoluteError { get; }
+    double TestMeanAbsoluteError { get; }
+    double TrainingRSquared { get; }
+    double TestRSquared { get; }
+    double TrainingRelativeError { get; }
+    double TestRelativeError { get; }
+    double TrainingNormalizedMeanSquaredError { get; }
+    double TestNormalizedMeanSquaredError { get; }
+    double TrainingTheilsUStatisticLast { get; }
+    double TestTheilsUStatisticLast { get; }
+    double TrainingTheilsUStatisticMean { get; }
+    double TestTheilsUStatisticMean { get; }
+    double TrainingDirectionalSymmetry { get; }
+    double TestDirectionalSymmetry { get; }
+    double TrainingWeightedDirectionalSymmetry { get; }
+    double TestWeightedDirectionalSymmetry { get; }
   }
 }
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs	(revision 7988)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.Instances.DataAnalysis/3.3/TimeSeries/TimeSeriesPrognosisInstanceProvider.cs	(revision 7989)
@@ -40,5 +40,5 @@
       IEnumerable<string> allowedInputVars = csvFileParser.VariableNames.Where(x => !x.Equals(targetVar));
 
-      ITimeSeriesPrognosisProblemData regData = new TimeSeriesPrognosisProblemData(dataset, allowedInputVars, new List<string> { targetVar });
+      ITimeSeriesPrognosisProblemData regData = new TimeSeriesPrognosisProblemData(dataset, allowedInputVars, targetVar);
 
       int trainingPartEnd = csvFileParser.Rows * 2 / 3;
