Index: anches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 8749)
+++ 	(revision )
@@ -1,46 +1,0 @@
-﻿namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
-  partial class SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView {
-    /// <summary> 
-    /// Required designer variable.
-    /// </summary>
-    private System.ComponentModel.IContainer components = null;
-
-    /// <summary> 
-    /// Clean up any resources being used.
-    /// </summary>
-    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-    protected override void Dispose(bool disposing) {
-      if (disposing && (components != null)) {
-        components.Dispose();
-      }
-      base.Dispose(disposing);
-    }
-
-    #region Component Designer generated code
-
-    /// <summary> 
-    /// Required method for Designer support - do not modify 
-    /// the contents of this method with the code editor.
-    /// </summary>
-    private void InitializeComponent() {
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
-      this.SuspendLayout();
-      // 
-      // chart
-      // 
-      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      // 
-      // SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView
-      // 
-      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-      this.Name = "SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView";
-      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
-      this.ResumeLayout(false);
-      this.PerformLayout();
-
-    }
-
-    #endregion
-  }
-}
Index: anches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views/3.4/SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 8749)
+++ 	(revision )
@@ -1,138 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
- *
- * This file is part of HeuristicLab.
- *
- * HeuristicLab is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * HeuristicLab is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
- */
-#endregion
-
-using System;
-using System.Linq;
-using System.Windows.Forms;
-using System.Windows.Forms.DataVisualization.Charting;
-using HeuristicLab.Algorithms.DataAnalysis;
-using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
-using HeuristicLab.MainForm;
-using HeuristicLab.Problems.DataAnalysis.Views;
-
-namespace HeuristicLab.Problems.DataAnalysis.Symbolic.TimeSeriesPrognosis.Views {
-  [View("Error Characteristics Curve")]
-  [Content(typeof(ISymbolicTimeSeriesPrognosisSolution))]
-  public partial class SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView : TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView {
-    private ITimeSeriesPrognosisSolution linearTimeSeriesPrognosisSolution;
-    private ITimeSeriesPrognosisSolution naiveSolution;
-
-    public SymbolicTimeSeriesPrognosisSolutionErrorCharacteristicsCurveView() {
-      InitializeComponent();
-    }
-
-    public new ISymbolicTimeSeriesPrognosisSolution Content {
-      get { return (ISymbolicTimeSeriesPrognosisSolution)base.Content; }
-      set { base.Content = value; }
-    }
-
-    protected override void OnContentChanged() {
-      if (Content != null) {
-        linearTimeSeriesPrognosisSolution = CreateLinearTimeSeriesPrognosisSolution();
-        naiveSolution = CreateNaiveSolution();
-      } else {
-        linearTimeSeriesPrognosisSolution = null;
-        naiveSolution = null;
-      }
-
-      base.OnContentChanged();
-    }
-
-    protected override void UpdateChart() {
-      base.UpdateChart();
-      if (Content == null || linearTimeSeriesPrognosisSolution == null) return;
-      AddTimeSeriesPrognosisSolution(linearTimeSeriesPrognosisSolution);
-      AddTimeSeriesPrognosisSolution(naiveSolution);
-    }
-
-    private ITimeSeriesPrognosisSolution CreateLinearTimeSeriesPrognosisSolution() {
-      if (Content == null) throw new InvalidOperationException();
-      double rmse, cvRmsError;
-      var problemData = (ITimeSeriesPrognosisProblemData)ProblemData.Clone();
-
-      //clear checked inputVariables
-      foreach (var inputVariable in problemData.InputVariables.CheckedItems) {
-        problemData.InputVariables.SetItemCheckedState(inputVariable.Value, false);
-      }
-
-      //check inputVariables used in the symbolic time series prognosis model
-      var usedVariables =
-        Content.Model.SymbolicExpressionTree.IterateNodesPostfix().OfType<VariableTreeNode>().Select(
-          node => node.VariableName).Distinct();
-      foreach (var variable in usedVariables) {
-        problemData.InputVariables.SetItemCheckedState(
-          problemData.InputVariables.Where(x => x.Value == variable).First(), true);
-      }
-
-      int maxLag = Content.Model.SymbolicExpressionTree.IterateNodesPostfix()
-        .OfType<LaggedVariableTreeNode>()
-        .Select(n => -n.Lag)
-        .Max();
-
-      var solution = LinearTimeSeriesPrognosis.CreateLinearTimeSeriesPrognosisSolution(problemData, maxLag, out rmse, out cvRmsError);
-      solution.Name = "Linear Model";
-      return solution;
-    }
-    private ITimeSeriesPrognosisSolution CreateNaiveSolution() {
-      if (Content == null) throw new InvalidOperationException();
-      double rmse, cvRmsError;
-      var problemData = (ITimeSeriesPrognosisProblemData)ProblemData.Clone();
-
-      //clear checked inputVariables
-      foreach (var inputVariable in problemData.InputVariables.CheckedItems) {
-        problemData.InputVariables.SetItemCheckedState(inputVariable.Value, false);
-      }
-
-      foreach (var variable in problemData.InputVariables) {
-        if (variable.Value == problemData.TargetVariable) {
-          problemData.InputVariables.SetItemCheckedState(variable, true);
-        }
-      }
-
-      int maxLag = 1;
-
-      var solution = LinearTimeSeriesPrognosis.CreateLinearTimeSeriesPrognosisSolution(problemData, maxLag, out rmse, out cvRmsError);
-      solution.Name = "AR(1) Model";
-      return solution;
-    }
-
-    protected override void Content_ModelChanged(object sender, EventArgs e) {
-      linearTimeSeriesPrognosisSolution = CreateLinearTimeSeriesPrognosisSolution();
-      naiveSolution = CreateNaiveSolution();
-      base.Content_ModelChanged(sender, e);
-    }
-
-    protected override void Content_ProblemDataChanged(object sender, EventArgs e) {
-      linearTimeSeriesPrognosisSolution = CreateLinearTimeSeriesPrognosisSolution();
-      naiveSolution = CreateNaiveSolution();
-      base.Content_ProblemDataChanged(sender, e);
-    }
-
-    private void chart_MouseDown(object sender, MouseEventArgs e) {
-      if (e.Clicks < 2) return;
-      HitTestResult result = chart.HitTest(e.X, e.Y);
-      if (result.ChartElementType != ChartElementType.LegendItem) return;
-      if (result.Series.Name == linearTimeSeriesPrognosisSolution.Name && result.Series.Name != naiveSolution.Name) return;
-
-      MainFormManager.MainForm.ShowContent((ITimeSeriesPrognosisSolution)result.Series.Tag);
-    }
-  }
-}
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 8749)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 8750)
@@ -352,4 +352,10 @@
     <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.Designer.cs">
       <DependentUpon>TimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisResultsView.cs</DependentUpon>
     </Compile>
     <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 8749)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 8750)
@@ -53,7 +53,9 @@
         contentType = Content.GetType();
         panel.Controls.Clear();
-        var viewType = MainFormManager.GetViewTypes(Content.GetType(), true).Where(t => typeof(DataAnalysisSolutionView).IsAssignableFrom(t)).FirstOrDefault();
+        var viewType = MainFormManager.GetViewTypes(Content.GetType(), true).FirstOrDefault(t => typeof(DataAnalysisSolutionView).IsAssignableFrom(t));
         if (viewType != null) {
-          view = (DataAnalysisSolutionView)Activator.CreateInstance(viewType);
+          view = (DataAnalysisSolutionView)MainFormManager.CreateView(viewType);
+          view.Locked = Locked;
+          view.ReadOnly = ReadOnly;
           view.Dock = DockStyle.Fill;
           view.Content = Content;
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 8750)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 8750)
@@ -0,0 +1,169 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisResultsView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.TrainingHorizonLabel = new System.Windows.Forms.Label();
+      this.TestHorizonLabel = new System.Windows.Forms.Label();
+      this.TrainingHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TestHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TrainingHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.TestHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonLabel);
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonLabel);
+      // 
+      // itemsListView
+      // 
+      this.itemsListView.Location = new System.Drawing.Point(3, 82);
+      this.itemsListView.Size = new System.Drawing.Size(244, 279);
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // TrainingHorizonLabel
+      // 
+      this.TrainingHorizonLabel.AutoSize = true;
+      this.TrainingHorizonLabel.Location = new System.Drawing.Point(3, 34);
+      this.TrainingHorizonLabel.Name = "TrainingHorizonLabel";
+      this.TrainingHorizonLabel.Size = new System.Drawing.Size(87, 13);
+      this.TrainingHorizonLabel.TabIndex = 7;
+      this.TrainingHorizonLabel.Text = "Training Horizon:";
+      // 
+      // TestHorizonLabel
+      // 
+      this.TestHorizonLabel.AutoSize = true;
+      this.TestHorizonLabel.Location = new System.Drawing.Point(3, 60);
+      this.TestHorizonLabel.Name = "TestHorizonLabel";
+      this.TestHorizonLabel.Size = new System.Drawing.Size(73, 13);
+      this.TestHorizonLabel.TabIndex = 8;
+      this.TestHorizonLabel.Text = "Test Horizon: ";
+      // 
+      // TrainingHorizonTextBox
+      // 
+      this.TrainingHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TrainingHorizonTextBox.Location = new System.Drawing.Point(96, 31);
+      this.TrainingHorizonTextBox.Name = "TrainingHorizonTextBox";
+      this.TrainingHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TrainingHorizonTextBox.TabIndex = 1;
+      this.TrainingHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TrainingHorizonTextBox_KeyDown);
+      this.TrainingHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TrainingHorizonTextBox_Validating);
+      this.TrainingHorizonTextBox.Validated += new System.EventHandler(this.TrainingHorizonTextBox_Validated);
+      // 
+      // TestHorizonTextBox
+      // 
+      this.TestHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TestHorizonTextBox.Location = new System.Drawing.Point(96, 57);
+      this.TestHorizonTextBox.Name = "TestHorizonTextBox";
+      this.TestHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TestHorizonTextBox.TabIndex = 1;
+      this.TestHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TestHorizonTextBox_KeyDown);
+      this.TestHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TestHorizonTextBox_Validating);
+      this.TestHorizonTextBox.Validated += new System.EventHandler(this.TestHorizonTextBox_Validated);
+      // 
+      // TrainingHorizonErrorProvider
+      // 
+      this.TrainingHorizonErrorProvider.BlinkRate = 0;
+      this.TrainingHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TrainingHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TestHorizonErrorProvider
+      // 
+      this.TestHorizonErrorProvider.BlinkRate = 0;
+      this.TestHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TestHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TimeSeriesPrognosisResultsView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeSeriesPrognosisResultsView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox TestHorizonTextBox;
+    private System.Windows.Forms.TextBox TrainingHorizonTextBox;
+    private System.Windows.Forms.Label TrainingHorizonLabel;
+    private System.Windows.Forms.Label TestHorizonLabel;
+    private System.Windows.Forms.ErrorProvider TrainingHorizonErrorProvider;
+    private System.Windows.Forms.ErrorProvider TestHorizonErrorProvider;
+
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 8750)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 8750)
@@ -0,0 +1,144 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("TimeSeriesPrognosisResultsView")]
+  [Content(typeof(TimeSeriesPrognosisResults), IsDefaultView = true)]
+  public partial class TimeSeriesPrognosisResultsView : ResultCollectionView {
+    public new TimeSeriesPrognosisResults Content {
+      get { return (TimeSeriesPrognosisResults)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool Locked {
+      get {
+        return base.Locked;
+      }
+      set {
+        base.Locked = value;
+      }
+    }
+
+    public TimeSeriesPrognosisResultsView() {
+      InitializeComponent();
+      TrainingHorizonErrorProvider.SetIconAlignment(TrainingHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TrainingHorizonErrorProvider.SetIconPadding(TrainingHorizonTextBox, 2);
+      TestHorizonErrorProvider.SetIconAlignment(TestHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TestHorizonErrorProvider.SetIconPadding(TestHorizonTextBox, 2);
+    }
+
+    #region Content Events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.TrainingHorizonChanged += new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged += new System.EventHandler(Content_TestHorizonChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      Content.TrainingHorizonChanged -= new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged -= new System.EventHandler(Content_TestHorizonChanged);
+      base.DeregisterContentEvents();
+    }
+
+    private void Content_TrainingHorizonChanged(object sender, System.EventArgs e) {
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void Content_TestHorizonChanged(object sender, System.EventArgs e) {
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        TrainingHorizonTextBox.Text = string.Empty;
+        TestHorizonTextBox.Text = string.Empty;
+      } else {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      //necessary cause this could be triggered by the base ctor when the controls are not created yet
+      if (TrainingHorizonTextBox == null || TestHorizonTextBox == null) return;
+      TrainingHorizonTextBox.Enabled = Content != null && !Locked;
+      TestHorizonTextBox.Enabled = Content != null && !Locked;
+    }
+
+    #region Control events
+    private void TrainingHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int trainingHorizon;
+      if (!int.TryParse(TrainingHorizonTextBox.Text, out trainingHorizon)) {
+        e.Cancel = true;
+        TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, "Please enter a numeric value.");
+        TrainingHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TrainingHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TrainingHorizon = int.Parse(TrainingHorizonTextBox.Text);
+      TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, string.Empty);
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void TrainingHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TrainingHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TrainingHorizonLabel.Select();  // select label to validate data
+      }
+    }
+
+    private void TestHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int testHorizon;
+      if (!int.TryParse(TestHorizonTextBox.Text, out testHorizon)) {
+        e.Cancel = true;
+        TestHorizonErrorProvider.SetError(TestHorizonTextBox, "Please enter a numeric value.");
+        TestHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TestHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TestHorizon = int.Parse(TestHorizonTextBox.Text);
+      TestHorizonErrorProvider.SetError(TestHorizonTextBox, string.Empty);
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+
+    private void TestHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TestHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+        TestHorizonLabel.Select();  // select label to validate data
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8749)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 8750)
@@ -153,4 +153,5 @@
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblem.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblemData.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisResults.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
     <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
Index: /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs
===================================================================
--- /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 8750)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 8750)
@@ -0,0 +1,494 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Prognosis Results", "Represents a collection of time series prognosis results.")]
+  public class TimeSeriesPrognosisResults : ResultCollection {
+    #region result names
+    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    protected const string PrognosisTestMeanSquaredErrorResultName = "Mean squared error (test)";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+    protected const string PrognosisTrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    protected const string PrognosisTestSquaredCorrelationResultName = "Pearson's R² (test)";
+    protected const string PrognosisTrainingRelativeErrorResultName = "Average relative error (training)";
+    protected const string PrognosisTestRelativeErrorResultName = "Average relative error (test)";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+    protected const string PrognosisTrainingMeanErrorResultName = "Mean error (training)";
+    protected const string PrognosisTestMeanErrorResultName = "Mean error (test)";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    protected const string PrognosisTestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (test)";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
+    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
+    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (training)";
+    protected const string PrognosisTestTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (test)";
+    #endregion
+
+    #region result descriptions
+    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
+    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
+    protected const string PrognosisTrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
+    protected const string PrognosisTestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
+    protected const string PrognosisTestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
+    protected const string PrognosisTestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the test partition";
+    #endregion
+
+    #region result properties
+    //prognosis results for different horizons
+    public double PrognosisTrainingMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRSquared {
+      get {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRSquared {
+      get {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+
+    public double PrognosisTrainingDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticMovingAverage {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMovingAverageResultName, PrognosisTrainingTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticMovingAverage {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTestTheilsUStatisticMovingAverageResultName, PrognosisTestTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value = value;
+      }
+    }
+    #endregion
+
+
+    private int trainingHorizon;
+    [Storable]
+    public int TrainingHorizon {
+      get { return trainingHorizon; }
+      set {
+        if (trainingHorizon != value) {
+          trainingHorizon = value;
+          OnTrainingHorizonChanged();
+        }
+      }
+    }
+
+    private int testHorizon;
+    [Storable]
+    public int TestHorizon {
+      get { return testHorizon; }
+      set {
+        if (testHorizon != value) {
+          testHorizon = value;
+          OnTestHorizonChanged();
+        }
+      }
+    }
+
+    private ITimeSeriesPrognosisSolution solution;
+    [Storable]
+    public ITimeSeriesPrognosisSolution Solution {
+      get { return solution; }
+    }
+
+    [StorableConstructor]
+    public TimeSeriesPrognosisResults(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisResults(TimeSeriesPrognosisResults original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisResults(this, cloner);
+    }
+
+    public TimeSeriesPrognosisResults(int trainingHorizon, int testHorizon, ITimeSeriesPrognosisSolution solution)
+      : base() {
+      this.trainingHorizon = trainingHorizon;
+      this.testHorizon = testHorizon;
+      this.solution = solution;
+      CalculateTrainingPrognosisResults();
+      CalculateTestPrognosisResults();
+    }
+
+    #region events
+    public event EventHandler TrainingHorizonChanged;
+    protected virtual void OnTrainingHorizonChanged() {
+      CalculateTrainingPrognosisResults();
+      var handler = TrainingHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler TestHorizonChanged;
+    protected virtual void OnTestHorizonChanged() {
+      CalculateTestPrognosisResults();
+      var handler = TestHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    private void CalculateTrainingPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      //MA model
+      const int movingAverageWindowSize = 10;
+      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, problemData.TargetVariable);
+
+      var trainingHorizions = problemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, problemData.TrainingPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingTargetValues = problemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+
+      IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
+
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+      double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+
+      PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
+      PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
+      PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
+      PrognosisTrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMovingAverage : double.PositiveInfinity;
+    }
+
+    private void CalculateTestPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      //MA model
+      const int movingAverageWindowSize = 10;
+      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, problemData.TargetVariable);
+
+      var testHorizions = problemData.TestIndices.Select(r => Math.Min(testHorizon, problemData.TestPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> testTargetValues = problemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> testEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<double> testStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+
+      IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
+
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+      double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+
+      PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
+      PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
+      PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
+      PrognosisTestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMovingAverage : double.PositiveInfinity;
+    }
+  }
+}
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 8749)
+++ /branches/HeuristicLab.TimeSeries/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 8750)
@@ -20,5 +20,4 @@
 #endregion
 
-using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -42,28 +41,5 @@
     protected const string TrainingTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (training)";
     protected const string TestTheilsUStatisticMovingAverageResultName = "Theil's U2 (moving average) (test)";
-
-    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Prognosis " + TrainingMeanSquaredErrorResultName;
-    protected const string PrognosisTestMeanSquaredErrorResultName = "Prognosis " + TestMeanSquaredErrorResultName;
-    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Prognosis " + TrainingMeanAbsoluteErrorResultName;
-    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Prognosis " + TestMeanAbsoluteErrorResultName;
-    protected const string PrognosisTrainingSquaredCorrelationResultName = "Prognosis " + TrainingSquaredCorrelationResultName;
-    protected const string PrognosisTestSquaredCorrelationResultName = "Prognosis " + TestSquaredCorrelationResultName;
-    protected const string PrognosisTrainingRelativeErrorResultName = "Prognosis " + TrainingRelativeErrorResultName;
-    protected const string PrognosisTestRelativeErrorResultName = "Prognosis " + TestRelativeErrorResultName;
-    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Prognosis " + TrainingNormalizedMeanSquaredErrorResultName;
-    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Prognosis " + TestNormalizedMeanSquaredErrorResultName;
-    protected const string PrognosisTrainingMeanErrorResultName = "Prognosis " + TrainingMeanErrorResultName;
-    protected const string PrognosisTestMeanErrorResultName = "Prognosis " + TestMeanErrorResultName;
-
-    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Prognosis " + TrainingDirectionalSymmetryResultName;
-    protected const string PrognosisTestDirectionalSymmetryResultName = "Prognosis " + TestDirectionalSymmetryResultName;
-    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Prognosis " + TrainingWeightedDirectionalSymmetryResultName;
-    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Prognosis " + TestWeightedDirectionalSymmetryResultName;
-    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Prognosis " + TrainingTheilsUStatisticAR1ResultName;
-    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Prognosis " + TestTheilsUStatisticLastResultName;
-    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Prognosis " + TrainingTheilsUStatisticMeanResultName;
-    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Prognosis " + TestTheilsUStatisticMeanResultName;
-    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultName = "Prognosis " + TrainingTheilsUStatisticMovingAverageResultName;
-    protected const string PrognosisTestTheilsUStatisticMovingAverageResultName = "Prognosis " + TestTheilsUStatisticMovingAverageResultName;
+    protected const string TimeSeriesPrognosisResultName = "Prognosis Results";
     #endregion
 
@@ -79,28 +55,5 @@
     protected const string TrainingTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the training partition";
     protected const string TestTheilsUStatisticMovingAverageResultDescription = "The Theil's U statistic (reference: moving average model) of the forecasts of the model on the test partition";
-
-    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = TrainingMeanSquaredErrorResultDescription;
-    protected const string PrognosisTestMeanSquaredErrorResultDescription = TestMeanSquaredErrorResultDescription;
-    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = TrainingMeanAbsoluteErrorResultDescription;
-    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = TestMeanAbsoluteErrorResultDescription;
-    protected const string PrognosisTrainingSquaredCorrelationResultDescription = TrainingSquaredCorrelationResultDescription;
-    protected const string PrognosisTestSquaredCorrelationResultDescription = TestSquaredCorrelationResultDescription;
-    protected const string PrognosisTrainingRelativeErrorResultDescription = TrainingRelativeErrorResultDescription;
-    protected const string PrognosisTestRelativeErrorResultDescription = TestRelativeErrorResultDescription;
-    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = TrainingNormalizedMeanSquaredErrorResultDescription;
-    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = TestNormalizedMeanSquaredErrorResultDescription;
-    protected const string PrognosisTrainingMeanErrorResultDescription = TrainingMeanErrorResultDescription;
-    protected const string PrognosisTestMeanErrorResultDescription = TestMeanErrorResultDescription;
-
-    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = TrainingDirectionalSymmetryResultDescription;
-    protected const string PrognosisTestDirectionalSymmetryResultDescription = TestDirectionalSymmetryResultDescription;
-    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = TrainingWeightedDirectionalSymmetryResultDescription;
-    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = TestWeightedDirectionalSymmetryResultDescription;
-    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = TrainingTheilsUStatisticAR1ResultDescription;
-    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = TestTheilsUStatisticAR1ResultDescription;
-    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = TrainingTheilsUStatisticMeanResultDescription;
-    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = TestTheilsUStatisticMeanResultDescription;
-    protected const string PrognosisTrainingTheilsUStatisticMovingAverageResultDescription = TrainingTheilsUStatisticMovingAverageResultDescription;
-    protected const string PrognosisTestTheilsUStatisticMovingAverageResultDescription = TestTheilsUStatisticMovingAverageResultDescription;
+    protected const string TimeSeriesPrognosisResultDescription = "The calculated results of predictions in the future.";
     #endregion
 
@@ -159,239 +112,16 @@
     }
 
-    //prognosis results for different horizons
-    public double PrognosisTrainingMeanSquaredError {
+    public TimeSeriesPrognosisResults TimeSeriesPrognosisResults {
       get {
-        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
+        if (!ContainsKey(TimeSeriesPrognosisResultName)) return null;
+        return (TimeSeriesPrognosisResults)this[TimeSeriesPrognosisResultName];
       }
-      private set {
-        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
+      set {
+        if (ContainsKey(TimeSeriesPrognosisResultName)) Remove(TimeSeriesPrognosisResultName);
+        Add(new Result(TimeSeriesPrognosisResultName, TimeSeriesPrognosisResultDescription, value));
       }
     }
-
-    public double PrognosisTestMeanSquaredError {
-      get {
-        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTrainingMeanAbsoluteError {
-      get {
-        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTestMeanAbsoluteError {
-      get {
-        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTrainingRSquared {
-      get {
-        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTestRSquared {
-      get {
-        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTrainingRelativeError {
-      get {
-        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTestRelativeError {
-      get {
-        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTrainingNormalizedMeanSquaredError {
-      get {
-        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTestNormalizedMeanSquaredError {
-      get {
-        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTrainingMeanError {
-      get {
-        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
-      }
-    }
-
-    public double PrognosisTestMeanError {
-      get {
-        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
-      }
-    }
-
-
-    public double PrognosisTrainingDirectionalSymmetry {
-      get {
-        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTestDirectionalSymmetry {
-      get {
-        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTrainingWeightedDirectionalSymmetry {
-      get {
-        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTestWeightedDirectionalSymmetry {
-      get {
-        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTrainingTheilsUStatisticAR1 {
-      get {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTestTheilsUStatisticAR1 {
-      get {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTrainingTheilsUStatisticMean {
-      get {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTestTheilsUStatisticMean {
-      get {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTrainingTheilsUStatisticMovingAverage {
-      get {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMovingAverageResultName, PrognosisTrainingTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMovingAverageResultName].Value).Value = value;
-      }
-    }
-    public double PrognosisTestTheilsUStatisticMovingAverage {
-      get {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) return double.NaN;
-        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value;
-      }
-      private set {
-        if (!ContainsKey(PrognosisTestTheilsUStatisticMovingAverageResultName)) Add(new Result(PrognosisTestTheilsUStatisticMovingAverageResultName, PrognosisTestTheilsUStatisticMovingAverageResultDescription, new DoubleValue()));
-        ((DoubleValue)this[PrognosisTestTheilsUStatisticMovingAverageResultName].Value).Value = value;
-      }
-    }
     #endregion
+
 
     public override IEnumerable<double> EstimatedValues {
@@ -485,97 +215,5 @@
 
     protected void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
-      OnlineCalculatorError errorState;
-      //mean model
-      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
-      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
-
-      //AR1 model
-      double alpha, beta;
-      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
-      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
-      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha);
-
-      //MA model
-      const int movingAverageWindowSize = 10;
-      var MovingAverageModel = new TimeSeriesPrognosisMovingAverageModel(movingAverageWindowSize, ProblemData.TargetVariable);
-
-      #region Calculate training quality measures
-      if (trainingHorizon != 1) {
-        var trainingHorizions = ProblemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, ProblemData.TrainingPartition.End - r)).ToList();
-        IEnumerable<IEnumerable<double>> trainingTargetValues = ProblemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
-        IEnumerable<IEnumerable<double>> trainingEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
-        IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
-        IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
-        IEnumerable<IEnumerable<double>> trainingMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TrainingIndices, trainingHorizions).ToList();
-
-        IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
-        IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
-
-        double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
-        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
-        double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
-        double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
-        double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
-        double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
-        PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
-
-        PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
-        PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
-        PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
-        PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
-        PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
-        PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
-        PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
-        PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
-        PrognosisTrainingTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMovingAverageModelPredictions, trainingEstimatedValues, out errorState);
-        PrognosisTrainingTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMovingAverage : double.PositiveInfinity;
-      }
-
-      #endregion
-
-      #region  Calculate test quality measures
-      if (testHorizon != 1) {
-        var testHorizions = ProblemData.TestIndices.Select(r => Math.Min(testHorizon, ProblemData.TestPartition.End - r)).ToList();
-        IEnumerable<IEnumerable<double>> testTargetValues = ProblemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, r)).ToList();
-        IEnumerable<IEnumerable<double>> testEstimatedValues = Model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
-        IEnumerable<double> testStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
-        IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
-        IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
-        IEnumerable<IEnumerable<double>> testMovingAverageModelPredictions = MovingAverageModel.GetPrognosedValues(ProblemData.Dataset, ProblemData.TestIndices, testHorizions).ToList();
-
-        IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
-        IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
-
-        double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
-        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
-        double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
-        double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
-        double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
-        double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
-        PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
-
-        PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
-        PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
-        PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
-        PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
-        PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
-        PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
-        PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
-        PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
-        PrognosisTestTheilsUStatisticMovingAverage = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMovingAverageModelPredictions, testEstimatedValues, out errorState);
-        PrognosisTestTheilsUStatisticMovingAverage = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMovingAverage : double.PositiveInfinity;
-      }
-
-      #endregion
+      TimeSeriesPrognosisResults = new TimeSeriesPrognosisResults(trainingHorizon, testHorizon, this);
     }
   }
