Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 7085)
@@ -95,4 +95,5 @@
     <Reference Include="LibSVM-1.6.3, Version=1.6.3.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
       <HintPath>..\..\bin\LibSVM-1.6.3.dll</HintPath>
+      <Private>False</Private>
     </Reference>
     <Reference Include="System" />
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 7085)
@@ -122,4 +122,6 @@
     <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
     <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
+    <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
+    <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionEnsembleProblemData.cs" />
     <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs">
@@ -147,4 +149,5 @@
     <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
     <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\IOnlineTimeSeriesCalculator.cs" />
     <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesBenchmarkProblemDataGenerator.cs" />
     <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisModel.cs" />
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 7085)
@@ -43,5 +43,5 @@
 
     private static readonly ClassificationEnsembleProblemData emptyProblemData;
-    public static ClassificationEnsembleProblemData EmptyProblemData {
+    public static new ClassificationEnsembleProblemData EmptyProblemData {
       get { return emptyProblemData; }
     }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 7085)
@@ -201,4 +201,5 @@
 
     public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      if (!Model.Models.Any()) yield break;
       var estimatedValuesEnumerators = (from model in Model.Models
                                         select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 7085)
@@ -28,5 +28,7 @@
   [Item("Classification Problem", "A general classification problem.")]
   [Creatable("Problems")]
-  public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem {
+  public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem, IStorableContent {
+    public string Filename { get; set; }
+
     [StorableConstructor]
     protected ClassificationProblem(bool deserializing) : base(deserializing) { }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 7085)
@@ -77,4 +77,12 @@
     }
 
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!this.ContainsKey(TrainingNormalizedGiniCoefficientResultName))
+        Add(new Result(TrainingNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the training partition.", new DoubleValue()));
+      if (!this.ContainsKey(TestNormalizedGiniCoefficientResultName))
+        Add(new Result(TestNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the test partition.", new DoubleValue()));
+    }
+
     protected void CalculateResults() {
       double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
@@ -84,7 +92,7 @@
 
       OnlineCalculatorError errorState;
-      double trainingAccuracy = OnlineAccuracyCalculator.Calculate(estimatedTrainingClassValues, originalTrainingClassValues, out errorState);
+      double trainingAccuracy = OnlineAccuracyCalculator.Calculate(originalTrainingClassValues, estimatedTrainingClassValues, out errorState);
       if (errorState != OnlineCalculatorError.None) trainingAccuracy = double.NaN;
-      double testAccuracy = OnlineAccuracyCalculator.Calculate(estimatedTestClassValues, originalTestClassValues, out errorState);
+      double testAccuracy = OnlineAccuracyCalculator.Calculate(originalTestClassValues, estimatedTestClassValues, out errorState);
       if (errorState != OnlineCalculatorError.None) testAccuracy = double.NaN;
 
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 7085)
@@ -108,12 +108,12 @@
 
       OnlineCalculatorError errorState;
-      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
-      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
 
-      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
-      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
 
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 7085)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 7085)
@@ -0,0 +1,60 @@
+﻿#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 System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Constant Regression Model", "A model that always returns the same constant value regardless of the presented input data.")]
+  public class ConstantRegressionModel : NamedItem, IRegressionModel {
+    [Storable]
+    private double constant;
+    public double Constant {
+      get { return constant; }
+    }
+
+    [StorableConstructor]
+    protected ConstantRegressionModel(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionModel(ConstantRegressionModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.constant = original.constant;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ConstantRegressionModel(this, cloner); }
+
+    public ConstantRegressionModel(double constant)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.constant = constant;
+    }
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      return rows.Select(row => Constant);
+    }
+
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConstantRegressionSolution(this, problemData);
+    }
+  }
+}
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 7085)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 7085)
@@ -0,0 +1,26 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "Constant Regression Solution", Description = "Represents a constant regression solution (model + data).")]
+  public class ConstantRegressionSolution : RegressionSolution {
+    public new ConstantRegressionModel Model {
+      get { return (ConstantRegressionModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    [StorableConstructor]
+    protected ConstantRegressionSolution(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionSolution(ConstantRegressionSolution original, Cloner cloner) : base(original, cloner) { }
+    public ConstantRegressionSolution(ConstantRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantRegressionSolution(this, cloner);
+    }
+  }
+}
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 7085)
@@ -64,5 +64,5 @@
     private void AfterDeserialization() {
       foreach (var model in Model.Models) {
-        IRegressionProblemData problemData = (IRegressionProblemData) ProblemData.Clone();
+        IRegressionProblemData problemData = (IRegressionProblemData)ProblemData.Clone();
         problemData.TrainingPartition.Start = trainingPartitions[model].Start;
         problemData.TrainingPartition.End = trainingPartitions[model].End;
@@ -202,4 +202,5 @@
 
     public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      if (!Model.Models.Any()) yield break;
       var estimatedValuesEnumerators = (from model in Model.Models
                                         select model.GetEstimatedValues(dataset, rows).GetEnumerator())
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 7085)
@@ -28,5 +28,7 @@
   [Item("Regression Problem", "A general regression problem.")]
   [Creatable("Problems")]
-  public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem {
+  public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem, IStorableContent {
+    public string Filename { get; set; }
+
     [StorableConstructor]
     protected RegressionProblem(bool deserializing) : base(deserializing) { }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 7085)
@@ -147,27 +147,27 @@
 
       OnlineCalculatorError errorState;
-      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
-      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
 
-      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
-      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
 
-      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
-      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
 
-      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
-      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
 
-      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
-      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
     }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 7085)
@@ -1565,5 +1565,5 @@
       problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
       problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
-      emptyProblemData = problemData;
+      emptyProblemData = problemData;      
     }
     #endregion
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 7085)
@@ -40,10 +40,10 @@
     private const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
     private const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
-    private const string TrainingDirectionalSymmetryResultName = "Directional symmetry (training)";
-    private const string TestDirectionalSymmetryResultName = "Directional symmetry (test)";
-    private const string TrainingWeightedDirectionalSymmetryResultName = "Weighted directional symmetry (training)";
-    private const string TestWeightedDirectionalSymmetryResultName = "Weighted directional symmetry (test)";
-    private const string TrainingTheilsUStatisticResultName = "Theil's U (training)";
-    private const string TestTheilsUStatisticResultName = "Theil's U (test)";
+    private const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    private const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    private const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    private const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    private const string TrainingTheilsUStatisticResultName = "Average Theil's U (training)";
+    private const string TestTheilsUStatisticResultName = "Average Theil's U (test)";
 
     public new ITimeSeriesPrognosisModel Model {
@@ -146,10 +146,10 @@
       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 directional symmetry of the output of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestDirectionalSymmetryResultName, "The directional symmetry of the output of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the output of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestWeightedDirectionalSymmetryResultName, "The weighted directional symmetry of the output of the model on the test partition", new DoubleValue()));
-      Add(new Result(TrainingTheilsUStatisticResultName, "The Theil's U statistic of the output of the model on the training partition", new DoubleValue()));
-      Add(new Result(TestTheilsUStatisticResultName, "The Theil's U statistic of the output 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 PercentValue()));
+      Add(new Result(TestDirectionalSymmetryResultName, "The average directional symmetry of the forecasts of the model on the test partition", new PercentValue()));
+      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(TrainingTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticResultName, "The average Theil's U statistic of the forecasts of the model on the test partition", new DoubleValue()));
     }
 
@@ -166,45 +166,59 @@
 
       OnlineCalculatorError errorState;
-      double trainingMse = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMse : double.NaN;
-      double testMse = OnlineMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testMse = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMse : double.NaN;
 
-      double trainingMae = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMae : double.NaN;
-      double testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testMae = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMae : double.NaN;
 
-      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
-      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
 
-      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
-      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
 
-      double trainingNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
       TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNmse : double.NaN;
-      double testNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testNmse = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
       TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNmse : double.NaN;
 
-      double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      var startTrainingValues = originalTrainingValues;
+      // each continuation is only one element long
+      var actualContinuationsTraining = from x in originalTrainingValues.Skip(1)
+                                        select Enumerable.Repeat(x, 1);
+      // each forecast is only one elemnt long
+      // disregards the first estimated value (we could include this again by extending the list of original values by one step to the left
+      // this is the easier way
+      var predictedContinuationsTraining = from x in estimatedTrainingValues.Skip(1)
+                                           select Enumerable.Repeat(x, 1);
+
+      var startTestValues = originalTestValues;
+      var actualContinuationsTest = from x in originalTestValues.Skip(1)
+                                    select Enumerable.Repeat(x, 1);
+      var predictedContinuationsTest = from x in estimatedTestValues.Skip(1)
+                                       select Enumerable.Repeat(x, 1);
+
+      double trainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
       TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingDirectionalSymmetry : double.NaN;
-      double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
       TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testDirectionalSymmetry : double.NaN;
 
-      double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
       TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? trainingWeightedDirectionalSymmetry : double.NaN;
-      double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
       TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? testWeightedDirectionalSymmetry : double.NaN;
 
-      double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate(estimatedTrainingValues, originalTrainingValues, out errorState);
+      double trainingTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTrainingValues, actualContinuationsTraining, predictedContinuationsTraining, out errorState);
       TrainingTheilsUStatistic = errorState == OnlineCalculatorError.None ? trainingTheilsU : double.NaN;
-      double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate(estimatedTestValues, originalTestValues, out errorState);
+      double testTheilsU = OnlineTheilsUStatisticCalculator.Calculate(startTestValues, actualContinuationsTest, predictedContinuationsTest, out errorState);
       TestTheilsUStatistic = errorState == OnlineCalculatorError.None ? testTheilsU : double.NaN;
-
-
     }
   }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 7085)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 7085)
@@ -0,0 +1,33 @@
+#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;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IOnlineTimeSeriesCalculator {
+    OnlineCalculatorError ErrorState { get; }
+    double Value { get; }
+    void Reset();
+    void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation);
+  }
+}
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 7085)
@@ -28,12 +28,14 @@
   public class NormalizedGiniCalculator {
 
-    public static double Calculate(IEnumerable<double> original, IEnumerable<double> estimated, out OnlineCalculatorError errorState) {
-      if (original.Count() != estimated.Count()) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      var originalValuesArr = originalValues.ToArray();
+      var estimatedValuesArr = estimatedValues.ToArray();
+      if (originalValuesArr.Count() != estimatedValuesArr.Count()) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
       }
-      double oe = Gini(original, estimated, out errorState);
+      double oe = Gini(originalValuesArr, estimatedValuesArr, out errorState);
       if (errorState != OnlineCalculatorError.None) return double.NaN;
 
-      return oe / (Gini(original, original, out errorState));
+      return oe / (Gini(originalValuesArr, originalValuesArr, out errorState));
     }
 
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 7085)
@@ -68,13 +68,13 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
       OnlineAccuracyCalculator accuracyCalculator = new OnlineAccuracyCalculator();
 
       // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         accuracyCalculator.Add(original, estimated);
         if (accuracyCalculator.ErrorState != OnlineCalculatorError.None) break;
@@ -83,6 +83,6 @@
       // check if both enumerators are at the end to make sure both enumerations have the same length
       if (accuracyCalculator.ErrorState == OnlineCalculatorError.None &&
-          (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+          (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
       } else {
         errorState = accuracyCalculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs	(revision 7085)
@@ -26,5 +26,5 @@
   public class OnlineCovarianceCalculator : IOnlineCalculator {
 
-    private double originalMean, estimatedMean, Cn;
+    private double xMean, yMean, Cn;
     private int n;
     public double Covariance {
@@ -49,11 +49,11 @@
       n = 0;
       Cn = 0.0;
-      originalMean = 0.0;
-      estimatedMean = 0.0;
+      xMean = 0.0;
+      yMean = 0.0;
       errorState = OnlineCalculatorError.InsufficientElementsAdded;
     }
 
-    public void Add(double original, double estimated) {
-      if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+    public void Add(double x, double y) {
+      if (double.IsNaN(y) || double.IsInfinity(y) || double.IsNaN(x) || double.IsInfinity(x) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
       } else {
@@ -62,10 +62,10 @@
 
         // online calculation of tMean
-        originalMean = originalMean + (original - originalMean) / n;
-        double delta = estimated - estimatedMean; // delta = (y - yMean(n-1))
-        estimatedMean = estimatedMean + delta / n;
+        xMean = xMean + (x - xMean) / n;
+        double delta = y - yMean; // delta = (y - yMean(n-1))
+        yMean = yMean + delta / n;
 
         // online calculation of covariance
-        Cn = Cn + delta * (original - originalMean); // C(n) = C(n-1) + (y - yMean(n-1)) (t - tMean(n))       
+        Cn = Cn + delta * (x - xMean); // C(n) = C(n-1) + (y - yMean(n-1)) (t - tMean(n))       
       }
     }
@@ -79,7 +79,7 @@
       // always move forward both enumerators (do not use short-circuit evaluation!)
       while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
-        covarianceCalculator.Add(original, estimated);
+        double x = secondEnumerator.Current;
+        double y = firstEnumerator.Current;
+        covarianceCalculator.Add(x, y);
         if (covarianceCalculator.ErrorState != OnlineCalculatorError.None) break;
       }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 7085)
@@ -22,10 +22,9 @@
 using System;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineDirectionalSymmetryCalculator : IOnlineCalculator {
-    private double prevEstimated;
-    private double prevOriginal;
+  public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
     private int n;
     private int nCorrect;
@@ -33,6 +32,6 @@
     public double DirectionalSymmetry {
       get {
-        if (n <= 1) return 0.0;
-        return (double)nCorrect / (n - 1) * 100.0;
+        if (n < 1) return 0.0;
+        return (double)nCorrect / n;
       }
     }
@@ -51,19 +50,33 @@
     }
 
-    public void Add(double original, double estimated) {
-      if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
-      } else if (n == 0) {
-        prevOriginal = original;
-        prevEstimated = estimated;
-        n++;
       } else {
-        if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) {
-          nCorrect++;
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        double prevActual = startValue;
+        double prevPredicted = startValue;
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // count a prediction correct if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - prevActual) * (predicted - prevPredicted) > 0.0 ||
+                (actual - prevActual).IsAlmost(predicted - prevPredicted)
+              ) {
+              nCorrect++;
+            }
+            n++;
+          }
         }
-        n++;
-        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
-        prevOriginal = original;
-        prevEstimated = estimated;
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
       }
     }
@@ -72,32 +85,24 @@
       n = 0;
       nCorrect = 0;
-      prevOriginal = double.NaN;
-      prevEstimated = double.NaN;
       errorState = OnlineCalculatorError.InsufficientElementsAdded;
     }
 
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
       OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
 
-      // add first element of time series as a reference point
-      firstEnumerator.MoveNext();
-      secondEnumerator.MoveNext();
-      dsCalculator.Add(firstEnumerator.Current, secondEnumerator.Current);
-      
-      // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
-        dsCalculator.Add(original, estimated);
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        dsCalculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
         if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
       }
 
-      // check if both enumerators are at the end to make sure both enumerations have the same length
+      // check if all enumerators are at the end to make sure both enumerations have the same length
       if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
-          (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
       } else {
         errorState = dsCalculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 7085)
@@ -65,13 +65,13 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
       OnlineMeanAbsoluteErrorCalculator maeCalculator = new OnlineMeanAbsoluteErrorCalculator();
 
       // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         maeCalculator.Add(original, estimated);
         if (maeCalculator.ErrorState != OnlineCalculatorError.None) break;
@@ -80,6 +80,6 @@
       // check if both enumerators are at the end to make sure both enumerations have the same length
       if (maeCalculator.ErrorState == OnlineCalculatorError.None &&
-         (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
       } else {
         errorState = maeCalculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 7085)
@@ -67,13 +67,13 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
       OnlineMeanAbsolutePercentageErrorCalculator calculator = new OnlineMeanAbsolutePercentageErrorCalculator();
 
       // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         calculator.Add(original, estimated);
         if (calculator.ErrorState != OnlineCalculatorError.None) break;
@@ -82,6 +82,6 @@
       // check if both enumerators are at the end to make sure both enumerations have the same length
       if (calculator.ErrorState == OnlineCalculatorError.None &&
-            (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+            (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and second estimatedValues doesn't match.");
       } else {
         errorState = calculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 7085)
@@ -65,13 +65,13 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
       OnlineMeanSquaredErrorCalculator mseCalculator = new OnlineMeanSquaredErrorCalculator();
 
       // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         mseCalculator.Add(original, estimated);
         if (mseCalculator.ErrorState != OnlineCalculatorError.None) break;
@@ -80,6 +80,6 @@
       // check if both enumerators are at the end to make sure both enumerations have the same length
       if (mseCalculator.ErrorState == OnlineCalculatorError.None &&
-         (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
       } else {
         errorState = mseCalculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 7085)
@@ -63,20 +63,20 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
       OnlineNormalizedMeanSquaredErrorCalculator normalizedMSECalculator = new OnlineNormalizedMeanSquaredErrorCalculator();
 
       //needed because otherwise the normalizedMSECalculator is in ErrorState.InsufficientValuesAdded
-      if (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      if (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         normalizedMSECalculator.Add(original, estimated);
       }
 
       // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
         normalizedMSECalculator.Add(original, estimated);
         if (normalizedMSECalculator.ErrorState != OnlineCalculatorError.None) break;
@@ -85,6 +85,6 @@
       // check if both enumerators are at the end to make sure both enumerations have the same length
       if (normalizedMSECalculator.ErrorState == OnlineCalculatorError.None &&
-           (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+           (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumeration doesn't match.");
       } else {
         errorState = normalizedMSECalculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 7085)
@@ -74,6 +74,6 @@
       // always move forward both enumerators (do not use short-circuit evaluation!)
       while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
+        double original = firstEnumerator.Current;
         double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
         rSquaredCalculator.Add(original, estimated);
         if (rSquaredCalculator.ErrorState != OnlineCalculatorError.None) break;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 7085)
@@ -22,11 +22,10 @@
 using System;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineTheilsUStatisticCalculator : IOnlineCalculator {
+  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator {
     private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
     private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
-    private double prevOriginal;
-    private int n;
 
     public double TheilsUStatistic {
@@ -52,27 +51,34 @@
     }
 
-    public void Add(double original, double estimated) {
-      if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
-      } else if (n == 0) {
-        prevOriginal = original;
-        n++;
       } else {
-        // error of predicted change
-        double errorEstimatedChange = (estimated - original);
-        squaredErrorMeanCalculator.Add(errorEstimatedChange * errorEstimatedChange);
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // error of predicted change
+            double errorPredictedChange = (predicted - startValue) - (actual - startValue);
+            squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
 
-        double errorNoChange = (original - prevOriginal);
-        unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
-        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
-        prevOriginal = original;
-        n++;
+            double errorNoChange = (actual - startValue);
+            unbiasedEstimatorMeanCalculator.Add(errorNoChange * errorNoChange);
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
       }
     }
 
-
     public void Reset() {
-      prevOriginal = double.NaN;
-      n = 0;
       squaredErrorMeanCalculator.Reset();
       unbiasedEstimatorMeanCalculator.Reset();
@@ -82,26 +88,20 @@
     #endregion
 
-    public static double Calculate(IEnumerable<double> estimatedValues, IEnumerable<double> originalValues, out OnlineCalculatorError errorState) {
-      IEnumerator<double> originalValuesEnumerator = originalValues.GetEnumerator();
-      IEnumerator<double> estimatedValuesEnumerator = estimatedValues.GetEnumerator();
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
       OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
 
-      // add first element of time series as a reference point
-      originalValuesEnumerator.MoveNext();
-      estimatedValuesEnumerator.MoveNext();
-      calculator.Add(originalValuesEnumerator.Current, estimatedValuesEnumerator.Current);
-
-      // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (originalValuesEnumerator.MoveNext() & estimatedValuesEnumerator.MoveNext()) {
-        double estimated = estimatedValuesEnumerator.Current;
-        double original = originalValuesEnumerator.Current;
-        calculator.Add(original, estimated);
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
         if (calculator.ErrorState != OnlineCalculatorError.None) break;
       }
 
-      // check if both enumerators are at the end to make sure both enumerations have the same length
+      // check if all enumerators are at the end to make sure both enumerations have the same length
       if (calculator.ErrorState == OnlineCalculatorError.None &&
-          (estimatedValuesEnumerator.MoveNext() || originalValuesEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
       } else {
         errorState = calculator.ErrorState;
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 7085)
@@ -22,10 +22,9 @@
 using System;
 using System.Collections.Generic;
+using HeuristicLab.Common;
 
 
 namespace HeuristicLab.Problems.DataAnalysis {
-  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineCalculator {
-    private double prevEstimated;
-    private double prevOriginal;
+  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
     private int n;
     private double correctSum;
@@ -52,22 +51,33 @@
     }
 
-    public void Add(double original, double estimated) {
-      if (double.IsNaN(estimated) || double.IsInfinity(estimated) || double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
         errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
-      } else if (n == 0) {
-        prevOriginal = original;
-        prevEstimated = estimated;
-        n++;
       } else {
-        double err = Math.Abs(original - estimated);
-        if ((original - prevOriginal) * (estimated - prevEstimated) >= 0.0) {
-          correctSum += err;
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            double err = Math.Abs(actual - predicted);
+            // count as correct only if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - startValue) * (predicted - startValue) > 0.0 ||
+              (actual - startValue).IsAlmost(predicted - startValue)) {
+              correctSum += err;
+            } else {
+              incorrectSum += err;
+            }
+            n++;
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
         } else {
-          incorrectSum += err;
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
         }
-        n++;
-        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
-        prevOriginal = original;
-        prevEstimated = estimated;
       }
     }
@@ -77,35 +87,27 @@
       correctSum = 0;
       incorrectSum = 0;
-      prevOriginal = double.NaN;
-      prevEstimated = double.NaN;
       errorState = OnlineCalculatorError.InsufficientElementsAdded;
     }
 
 
-    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
-      IEnumerator<double> firstEnumerator = first.GetEnumerator();
-      IEnumerator<double> secondEnumerator = second.GetEnumerator();
-      OnlineWeightedDirectionalSymmetryCalculator dsCalculator = new OnlineWeightedDirectionalSymmetryCalculator();
-      
-      // add first element of time series as a reference point
-      firstEnumerator.MoveNext();
-      secondEnumerator.MoveNext();
-      dsCalculator.Add(firstEnumerator.Current, secondEnumerator.Current);
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
 
-      // always move forward both enumerators (do not use short-circuit evaluation!)
-      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
-        double estimated = secondEnumerator.Current;
-        double original = firstEnumerator.Current;
-        dsCalculator.Add(original, estimated);
-        if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
       }
 
-      // check if both enumerators are at the end to make sure both enumerations have the same length
-      if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
-          (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
-        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
       } else {
-        errorState = dsCalculator.ErrorState;
-        return dsCalculator.WeightedDirectionalSymmetry;
+        errorState = calculator.ErrorState;
+        return calculator.WeightedDirectionalSymmetry;
       }
     }
Index: branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/TableFileParser.cs
===================================================================
--- branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/TableFileParser.cs	(revision 7044)
+++ branches/RegressionBenchmarks/HeuristicLab.Problems.DataAnalysis/3.4/TableFileParser.cs	(revision 7085)
@@ -156,11 +156,15 @@
         } else if (OccurrencesOf(charCounts, ',') > 10) {
           // no points and many commas
-          int countCommaNonDigitPairs = 0;
-          for (int i = 0; i < charsRead - 1; i++) {
-            if (buffer[i] == ',' && !Char.IsDigit(buffer[i + 1])) {
-              countCommaNonDigitPairs++;
+          // count the number of tokens (chains of only digits and commas) that contain multiple comma characters
+          int tokensWithMultipleCommas = 0;
+          for (int i = 0; i < charsRead; i++) {
+            int nCommas = 0;
+            while (i < charsRead && (buffer[i] == ',' || Char.IsDigit(buffer[i]))) {
+              if (buffer[i] == ',') nCommas++;
+              i++;
             }
-          }
-          if (countCommaNonDigitPairs > 10) {
+            if (nCommas > 2) tokensWithMultipleCommas++;
+          }
+          if (tokensWithMultipleCommas > 1) {
             // English format (only integer values) with ',' as separator
             numberFormat = NumberFormatInfo.InvariantInfo;
