Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/HeuristicLab.Problems.DynamicalSystemsModelling-3.3.csproj
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/HeuristicLab.Problems.DynamicalSystemsModelling-3.3.csproj	(revision 16398)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/HeuristicLab.Problems.DynamicalSystemsModelling-3.3.csproj	(revision 16399)
@@ -104,4 +104,5 @@
       <HintPath>..\..\bin\ALGLIB-3.7.0.dll</HintPath>
     </Reference>
+    <Reference Include="Microsoft.CSharp" />
     <Reference Include="System" />
     <Reference Include="System.Core">
@@ -109,4 +110,5 @@
     </Reference>
     <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
   </ItemGroup>
   <ItemGroup>
@@ -116,4 +118,11 @@
     <Compile Include="Problem.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Solution.cs" />
+    <Compile Include="SolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="SolutionView.Designer.cs">
+      <DependentUpon>SolutionView.cs</DependentUpon>
+    </Compile>
     <Compile Include="Vector.cs" />
   </ItemGroup>
@@ -129,4 +138,8 @@
       <Name>HeuristicLab.Algorithms.DataAnalysis-3.4</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis.Views\3.3\HeuristicLab.Analysis.Views-3.3.csproj">
+      <Project>{76945D76-CA61-4147-9DC2-0ACDCDDF87F9}</Project>
+      <Name>HeuristicLab.Analysis.Views-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
       <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
@@ -148,4 +161,8 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
+      <Project>{E226881D-315F-423D-B419-A766FE0D8685}</Project>
+      <Name>HeuristicLab.Core.Views-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
       <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project>
@@ -153,4 +170,8 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data.Views\3.3\HeuristicLab.Data.Views-3.3.csproj">
+      <Project>{72104A0B-90E7-42F3-9ABE-9BBBADD4B943}</Project>
+      <Name>HeuristicLab.Data.Views-3.3</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
       <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project>
@@ -162,4 +183,12 @@
       <Name>HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4</Name>
       <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm.WindowsForms\3.3\HeuristicLab.MainForm.WindowsForms-3.3.csproj">
+      <Project>{AB687BBE-1BFE-476B-906D-44237135431D}</Project>
+      <Name>HeuristicLab.MainForm.WindowsForms-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.MainForm\3.3\HeuristicLab.MainForm-3.3.csproj">
+      <Project>{3BD61258-31DA-4B09-89C0-4F71FEF5F05A}</Project>
+      <Name>HeuristicLab.MainForm-3.3</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
@@ -235,4 +264,9 @@
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </Content>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="SolutionView.resx">
+      <DependentUpon>SolutionView.cs</DependentUpon>
+    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs	(revision 16398)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Problem.cs	(revision 16399)
@@ -198,7 +198,10 @@
     public override double Evaluate(Individual individual, IRandom random) {
       var trees = individual.Values.Select(v => v.Value).OfType<ISymbolicExpressionTree>().ToArray(); // extract all trees from individual
-      // write back optimized parameters to tree nodes instead of the separate OptTheta variable
-      // retreive optimized parameters from nodes?
-
+                                                                                                      // write back optimized parameters to tree nodes instead of the separate OptTheta variable
+                                                                                                      // retreive optimized parameters from nodes?
+
+      var problemData = ProblemData;
+      var targetVars = TargetVariables.CheckedItems.OrderBy(i => i.Index).Select(i => i.Value.Value).ToArray();
+      var latentVariables = Enumerable.Range(1, NumberOfLatentVariables).Select(i => "λ" + i).ToArray(); // TODO: must coincide with the variables which are actually defined in the grammar and also for which we actually have trees
       if (OptimizeParametersForEpisodes) {
         int eIdx = 0;
@@ -208,5 +211,5 @@
           double[] optTheta;
           double nmse;
-          OptimizeForEpisodes(trees, random, new[] { episode }, out optTheta, out nmse);
+          OptimizeForEpisodes(trees, problemData, targetVars, latentVariables, random, new[] { episode }, MaximumParameterOptimizationIterations, NumericIntegrationSteps, OdeSolver, out optTheta, out nmse);
           individual["OptTheta_" + eIdx] = new DoubleArray(optTheta); // write back optimized parameters so that we can use them in the Analysis method
           eIdx++;
@@ -218,5 +221,5 @@
         double[] optTheta;
         double nmse;
-        OptimizeForEpisodes(trees, random, TrainingEpisodes, out optTheta, out nmse);
+        OptimizeForEpisodes(trees, problemData, targetVars, latentVariables, random, TrainingEpisodes, MaximumParameterOptimizationIterations, NumericIntegrationSteps, OdeSolver, out optTheta, out nmse);
         individual["OptTheta"] = new DoubleArray(optTheta); // write back optimized parameters so that we can use them in the Analysis method
         return nmse;
@@ -224,14 +227,17 @@
     }
 
-    private void OptimizeForEpisodes(
+    public static void OptimizeForEpisodes(
       ISymbolicExpressionTree[] trees,
+      IRegressionProblemData problemData,
+      string[] targetVars,
+      string[] latentVariables,
       IRandom random,
       IEnumerable<IntRange> episodes,
+      int maxParameterOptIterations,
+      int numericIntegrationSteps,
+      string odeSolver,
       out double[] optTheta,
       out double nmse) {
       var rows = episodes.SelectMany(e => Enumerable.Range(e.Start, e.End - e.Start)).ToArray();
-      var problemData = ProblemData;
-      var targetVars = TargetVariables.CheckedItems.OrderBy(i => i.Index).Select(i => i.Value.Value).ToArray();
-      var latentVariables = Enumerable.Range(1, NumberOfLatentVariables).Select(i => "λ" + i).ToArray(); // TODO: must coincide with the variables which are actually defined in the grammar and also for which we actually have trees
       var targetValues = new double[rows.Length, targetVars.Length];
 
@@ -267,8 +273,8 @@
         alglib.minlbfgsreport report;
         alglib.minlbfgscreate(Math.Min(theta.Length, 5), theta, out state);
-        alglib.minlbfgssetcond(state, 0.0, 0.0, 0.0, MaximumParameterOptimizationIterations);
+        alglib.minlbfgssetcond(state, 0.0, 0.0, 0.0, maxParameterOptIterations);
         //alglib.minlbfgssetgradientcheck(state, 1e-6);
         alglib.minlbfgsoptimize(state, EvaluateObjectiveAndGradient, null,
-          new object[] { trees, targetVars, problemData, targetValues, episodes.ToArray(), NumericIntegrationSteps, latentVariables, OdeSolver }); //TODO: create a type
+          new object[] { trees, targetVars, problemData, targetValues, episodes.ToArray(), numericIntegrationSteps, latentVariables, odeSolver }); //TODO: create a type
 
         alglib.minlbfgsresults(state, out optTheta, out report);
@@ -307,5 +313,5 @@
       nmse = double.NaN;
       EvaluateObjectiveAndGradient(optTheta, ref nmse, grad,
-        new object[] { trees, targetVars, problemData, targetValues, episodes.ToArray(), NumericIntegrationSteps, latentVariables, OdeSolver });
+        new object[] { trees, targetVars, problemData, targetValues, episodes.ToArray(), numericIntegrationSteps, latentVariables, odeSolver });
       if (double.IsNaN(nmse) || double.IsInfinity(nmse)) { nmse = 10E6; return; } // return a large value (TODO: be consistent by using NMSE)
     }
@@ -385,6 +391,9 @@
         results.Add(new Result("Models", typeof(VariableCollection)));
       }
-      if(!results.ContainsKey("SNMSE")) {
+      if (!results.ContainsKey("SNMSE")) {
         results.Add(new Result("SNMSE", typeof(DoubleValue)));
+      }
+      if (!results.ContainsKey("Solution")) {
+        results.Add(new Result("Solution", typeof(Solution)));
       }
 
@@ -517,9 +526,36 @@
         results["Prediction (training)"].Value = trainingList.AsReadOnly();
         results["Prediction (test)"].Value = testList.AsReadOnly();
+
+
         #region simplification of models
         // TODO the dependency of HeuristicLab.Problems.DataAnalysis.Symbolic is not ideal
         var models = new VariableCollection();    // to store target var names and original version of tree
 
+        var optimizedTrees = new List<ISymbolicExpressionTree>();
         int nextParIdx = 0;
+        for (int idx = 0; idx < trees.Length; idx++) {
+          var tree = trees[idx];
+          optimizedTrees.Add(new SymbolicExpressionTree(FixParameters(tree.Root, optTheta.ToArray(), ref nextParIdx)));
+        }
+        var ds = problemData.Dataset;
+        var newVarNames = Enumerable.Range(0, nextParIdx).Select(i => "c_" + i).ToArray();
+        var allVarNames = ds.DoubleVariables.Concat(newVarNames);
+        var newVarValues = Enumerable.Range(0, nextParIdx).Select(i => "c_" + i).ToArray();
+        var allVarValues = ds.DoubleVariables.Select(varName => ds.GetDoubleValues(varName).ToList())
+          .Concat(Enumerable.Range(0, nextParIdx).Select(i => Enumerable.Repeat(optTheta[i], ds.Rows).ToList()))
+          .ToList();
+        var newDs = new Dataset(allVarNames, allVarValues);
+        var newProblemData = new RegressionProblemData(newDs, problemData.AllowedInputVariables.Concat(newVarValues).ToArray(), problemData.TargetVariable);
+        results["Solution"].Value = new Solution(optimizedTrees.ToArray(),
+                   // optTheta,
+                   newProblemData,
+                   targetVars,
+                   latentVariables,
+                   TrainingEpisodes,
+                   OdeSolver,
+                   NumericIntegrationSteps);
+
+
+        nextParIdx = 0;
         for (int idx = 0; idx < trees.Length; idx++) {
           var varName = string.Empty;
@@ -558,4 +594,5 @@
 
         }
+
         results["Models"].Value = models;
         #endregion
@@ -576,5 +613,5 @@
     // for a solver with the necessary features see: https://computation.llnl.gov/projects/sundials/cvodes
 
-    private static IEnumerable<Tuple<double, Vector>[]> Integrate(
+    public static IEnumerable<Tuple<double, Vector>[]> Integrate(
       ISymbolicExpressionTree[] trees, IDataset dataset,
       string[] inputVariables, string[] targetVariables, string[] latentVariables, IEnumerable<IntRange> episodes,
@@ -999,6 +1036,6 @@
 
 
-        foreach(var node in nodeValues.Keys.ToArray()) {
-          if(node.SubtreeCount == 0 && !IsConstantNode(node)) {
+        foreach (var node in nodeValues.Keys.ToArray()) {
+          if (node.SubtreeCount == 0 && !IsConstantNode(node)) {
             // update values for (latent) variables
             var varName = node.Symbol.Name;
@@ -1168,8 +1205,8 @@
 
     private static bool IsConstantNode(ISymbolicExpressionTreeNode n) {
-      return n.Symbol.Name.StartsWith("θ");
+      return n.Symbol.Name[0] == 'θ';
     }
     private static bool IsLatentVariableNode(ISymbolicExpressionTreeNode n) {
-      return n.Symbol.Name.StartsWith("λ");
+      return n.Symbol.Name[0] == 'λ';
     }
     private static bool IsVariableNode(ISymbolicExpressionTreeNode n) {
@@ -1232,4 +1269,40 @@
 
       return g;
+    }
+
+
+
+
+
+    private ISymbolicExpressionTreeNode FixParameters(ISymbolicExpressionTreeNode n, double[] parameterValues, ref int nextParIdx) {
+      ISymbolicExpressionTreeNode translatedNode = null;
+      if (n.Symbol is StartSymbol) {
+        translatedNode = new StartSymbol().CreateTreeNode();
+      } else if (n.Symbol is ProgramRootSymbol) {
+        translatedNode = new ProgramRootSymbol().CreateTreeNode();
+      } else if (n.Symbol.Name == "+") {
+        translatedNode = new SimpleSymbol("+", 2).CreateTreeNode();
+      } else if (n.Symbol.Name == "-") {
+        translatedNode = new SimpleSymbol("-", 2).CreateTreeNode();
+      } else if (n.Symbol.Name == "*") {
+        translatedNode = new SimpleSymbol("*", 2).CreateTreeNode();
+      } else if (n.Symbol.Name == "%") {
+        translatedNode = new SimpleSymbol("%", 2).CreateTreeNode();
+      } else if (n.Symbol.Name == "sin") {
+        translatedNode = new SimpleSymbol("sin", 1).CreateTreeNode();
+      } else if (n.Symbol.Name == "cos") {
+        translatedNode = new SimpleSymbol("cos", 1).CreateTreeNode();
+      } else if (n.Symbol.Name == "sqr") {
+        translatedNode = new SimpleSymbol("sqr", 1).CreateTreeNode();
+      } else if (IsConstantNode(n)) {
+        translatedNode = new SimpleSymbol("c_" + nextParIdx, 0).CreateTreeNode();
+        nextParIdx++;
+      } else {
+        translatedNode = new SimpleSymbol(n.Symbol.Name, n.SubtreeCount).CreateTreeNode();
+      }
+      foreach (var child in n.Subtrees) {
+        translatedNode.AddSubtree(FixParameters(child, parameterValues, ref nextParIdx));
+      }
+      return translatedNode;
     }
 
Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Solution.cs
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Solution.cs	(revision 16399)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/Solution.cs	(revision 16399)
@@ -0,0 +1,106 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Problems.DynamicalSystemsModelling {
+  [StorableClass]
+  public class Solution : Item {
+    [Storable]
+    private ISymbolicExpressionTree[] trees;
+    public ISymbolicExpressionTree[] Trees {
+      get { return trees; }
+    }
+    // [Storable]
+    // private double[] theta;
+
+    [Storable]
+    private IRegressionProblemData problemData;
+    public IRegressionProblemData ProblemData {
+      get { return problemData; }
+    }
+    [Storable]
+    private string[] targetVars;
+    public string[] TargetVariables {
+      get { return targetVars; }
+    }
+    [Storable]
+    private string[] latentVariables;
+    public string[] LatentVariables {
+      get { return latentVariables; }
+    }
+    [Storable]
+    private IEnumerable<IntRange> trainingEpisodes;
+    public IEnumerable<IntRange> TrainingEpisodes {
+      get { return trainingEpisodes; }
+    }
+    [Storable]
+    private string odeSolver;
+    [Storable]
+    private int numericIntegrationSteps;
+
+    [StorableConstructor]
+    private Solution(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+
+    // cloning 
+    private Solution(Solution original, Cloner cloner)
+      : base(original, cloner) {
+      this.trees = new ISymbolicExpressionTree[original.trees.Length];
+      for (int i = 0; i < trees.Length; i++) this.trees[i] = cloner.Clone(original.trees[i]);
+      // this.theta = new double[original.theta.Length];
+      // Array.Copy(original.theta, this.theta, this.theta.Length);
+      this.problemData = cloner.Clone(original.problemData);
+      this.targetVars = original.TargetVariables.ToArray();
+      this.latentVariables = original.LatentVariables.ToArray();
+      this.trainingEpisodes = original.TrainingEpisodes.Select(te => cloner.Clone(te)).ToArray();
+      this.odeSolver = original.odeSolver;
+      this.numericIntegrationSteps = original.numericIntegrationSteps;
+    }
+
+    public Solution(ISymbolicExpressionTree[] trees,
+      IRegressionProblemData problemData,
+      string[] targetVars, string[] latentVariables, IEnumerable<IntRange> trainingEpisodes,
+      string odeSolver, int numericIntegrationSteps) : base() {
+      this.trees = trees;
+
+      this.problemData = problemData;
+      this.targetVars = targetVars;
+      this.latentVariables = latentVariables;
+      this.trainingEpisodes = trainingEpisodes;
+      this.odeSolver = odeSolver;
+      this.numericIntegrationSteps = numericIntegrationSteps;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new Solution(this, cloner);
+    }
+
+    public IEnumerable<double[]> Predict(IntRange episode, int forecastHorizon) {
+      var forecastEpisode = new IntRange(episode.Start, episode.End + forecastHorizon);
+      double nmse = double.NaN;
+      double[] optL0;
+      var random = new FastRandom(12345);
+      Problem.OptimizeForEpisodes(trees, problemData, targetVars, latentVariables, random, new[] { forecastEpisode }, 100, numericIntegrationSteps, odeSolver, out optL0, out nmse);
+      var predictions = Problem.Integrate(
+         trees,
+         problemData.Dataset,
+         problemData.AllowedInputVariables.ToArray(),
+         targetVars,
+         latentVariables,
+         new[] { forecastEpisode },
+         optL0,
+         odeSolver,
+         numericIntegrationSteps).ToArray();
+      return predictions.Select(p => p.Select(pi => pi.Item1).ToArray()).ToArray();
+    }
+  }
+}
Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.Designer.cs
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.Designer.cs	(revision 16399)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.Designer.cs	(revision 16399)
@@ -0,0 +1,186 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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.DynamicalSystemsModelling {
+  partial class SolutionView {
+    /// <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.animationTimer = new System.Windows.Forms.Timer(this.components);
+      this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
+      this.updateButton = new System.Windows.Forms.Button();
+      this.forecastTextbox = new System.Windows.Forms.TextBox();
+      this.forecastLabel = new System.Windows.Forms.Label();
+      this.startLabel = new System.Windows.Forms.Label();
+      this.episodeStartTextbox = new System.Windows.Forms.TextBox();
+      this.endLabel = new System.Windows.Forms.Label();
+      this.episodeEndTextbox = new System.Windows.Forms.TextBox();
+      this.trackBar = new System.Windows.Forms.TrackBar();
+      ((System.ComponentModel.ISupportInitialize)(this.trackBar)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // animationTimer
+      // 
+      this.animationTimer.Interval = 15;
+      // 
+      // tableLayoutPanel
+      // 
+      this.tableLayoutPanel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.tableLayoutPanel.ColumnCount = 1;
+      this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
+      this.tableLayoutPanel.GrowStyle = System.Windows.Forms.TableLayoutPanelGrowStyle.FixedSize;
+      this.tableLayoutPanel.Location = new System.Drawing.Point(0, 109);
+      this.tableLayoutPanel.Name = "tableLayoutPanel";
+      this.tableLayoutPanel.RowCount = 2;
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+      this.tableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
+      this.tableLayoutPanel.Size = new System.Drawing.Size(629, 344);
+      this.tableLayoutPanel.TabIndex = 5;
+      // 
+      // updateButton
+      // 
+      this.updateButton.Location = new System.Drawing.Point(350, 2);
+      this.updateButton.Name = "updateButton";
+      this.updateButton.Size = new System.Drawing.Size(75, 23);
+      this.updateButton.TabIndex = 3;
+      this.updateButton.Text = "Update";
+      this.updateButton.UseVisualStyleBackColor = true;
+      this.updateButton.Click += new System.EventHandler(this.updateButton_Click);
+      // 
+      // forecastTextbox
+      // 
+      this.forecastTextbox.Location = new System.Drawing.Point(244, 4);
+      this.forecastTextbox.Name = "forecastTextbox";
+      this.forecastTextbox.Size = new System.Drawing.Size(100, 20);
+      this.forecastTextbox.TabIndex = 2;
+      this.forecastTextbox.Text = "180";
+      // 
+      // forecastLabel
+      // 
+      this.forecastLabel.AutoSize = true;
+      this.forecastLabel.Location = new System.Drawing.Point(187, 7);
+      this.forecastLabel.Name = "forecastLabel";
+      this.forecastLabel.Size = new System.Drawing.Size(51, 13);
+      this.forecastLabel.TabIndex = 8;
+      this.forecastLabel.Text = "Forecast:";
+      // 
+      // startLabel
+      // 
+      this.startLabel.AutoSize = true;
+      this.startLabel.Location = new System.Drawing.Point(4, 6);
+      this.startLabel.Name = "startLabel";
+      this.startLabel.Size = new System.Drawing.Size(71, 13);
+      this.startLabel.TabIndex = 6;
+      this.startLabel.Text = "Episode start:";
+      // 
+      // episodeStartTextbox
+      // 
+      this.episodeStartTextbox.Location = new System.Drawing.Point(81, 4);
+      this.episodeStartTextbox.Name = "episodeStartTextbox";
+      this.episodeStartTextbox.Size = new System.Drawing.Size(100, 20);
+      this.episodeStartTextbox.TabIndex = 0;
+      this.episodeStartTextbox.Text = "0";
+      this.episodeStartTextbox.Validating += new System.ComponentModel.CancelEventHandler(this.episodeStartTextbox_Validating);
+      this.episodeStartTextbox.Validated += new System.EventHandler(this.episodeStartTextbox_Validated);
+      // 
+      // endLabel
+      // 
+      this.endLabel.AutoSize = true;
+      this.endLabel.Location = new System.Drawing.Point(4, 35);
+      this.endLabel.Name = "endLabel";
+      this.endLabel.Size = new System.Drawing.Size(69, 13);
+      this.endLabel.TabIndex = 7;
+      this.endLabel.Text = "Episode end:";
+      // 
+      // episodeEndTextbox
+      // 
+      this.episodeEndTextbox.Location = new System.Drawing.Point(81, 32);
+      this.episodeEndTextbox.Name = "episodeEndTextbox";
+      this.episodeEndTextbox.Size = new System.Drawing.Size(100, 20);
+      this.episodeEndTextbox.TabIndex = 1;
+      this.episodeEndTextbox.Text = "10";
+      // 
+      // trackBar
+      // 
+      this.trackBar.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.trackBar.Location = new System.Drawing.Point(40, 58);
+      this.trackBar.Name = "trackBar";
+      this.trackBar.Size = new System.Drawing.Size(586, 45);
+      this.trackBar.TabIndex = 4;
+      this.trackBar.ValueChanged += new System.EventHandler(this.trackBar_Validated);
+      // 
+      // SolutionView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.trackBar);
+      this.Controls.Add(this.endLabel);
+      this.Controls.Add(this.episodeEndTextbox);
+      this.Controls.Add(this.startLabel);
+      this.Controls.Add(this.episodeStartTextbox);
+      this.Controls.Add(this.forecastLabel);
+      this.Controls.Add(this.forecastTextbox);
+      this.Controls.Add(this.updateButton);
+      this.Controls.Add(this.tableLayoutPanel);
+      this.Name = "SolutionView";
+      this.Size = new System.Drawing.Size(629, 456);
+      ((System.ComponentModel.ISupportInitialize)(this.trackBar)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+    private System.Windows.Forms.Timer animationTimer;
+    private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
+    private System.Windows.Forms.Button updateButton;
+    private System.Windows.Forms.TextBox forecastTextbox;
+    private System.Windows.Forms.Label forecastLabel;
+    private System.Windows.Forms.Label startLabel;
+    private System.Windows.Forms.TextBox episodeStartTextbox;
+    private System.Windows.Forms.Label endLabel;
+    private System.Windows.Forms.TextBox episodeEndTextbox;
+    private System.Windows.Forms.TrackBar trackBar;
+  }
+}
Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.cs
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.cs	(revision 16399)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.cs	(revision 16399)
@@ -0,0 +1,141 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 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 HeuristicLab.Analysis;
+using HeuristicLab.Analysis.Views;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DynamicalSystemsModelling {
+  [View("Solution View")]
+  [Content(typeof(Solution), true)]
+  public sealed partial class SolutionView : ItemView {
+    public new Solution Content {
+      get { return (Solution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public SolutionView() {
+      InitializeComponent();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        episodeStartTextbox.Text = string.Empty;
+        episodeEndTextbox.Text = string.Empty;
+      } else {
+        var episode = Content.TrainingEpisodes.First();
+        episodeStartTextbox.Text = episode.Start.ToString();
+        episodeEndTextbox.Text = episode.End.ToString();
+      }
+      UpdatePredictions();
+    }
+
+    private void UpdatePredictions() {
+      tableLayoutPanel.Controls.Clear();
+      if (Content == null) return;
+      tableLayoutPanel.RowCount = Content.Trees.Length;
+      var targetVars = Content.TargetVariables;
+      var calculatedVars = Content.TargetVariables.Concat(Content.LatentVariables).ToArray();
+      var ds = Content.ProblemData.Dataset;
+      var predictionEpisode = new IntRange(int.Parse(episodeStartTextbox.Text), int.Parse(episodeEndTextbox.Text));
+
+      trackBar.Minimum = 0;
+      trackBar.Maximum = ds.Rows;
+      var forecastHorizon = 0;
+      int.TryParse(forecastTextbox.Text, out forecastHorizon);
+      // trackBar.Value = predictionEpisode.Start;
+
+      var predictions = Content.Predict(predictionEpisode, forecastHorizon).ToArray();
+      var trainingPredictions = predictions.Take(predictionEpisode.Size).ToArray();
+      var forecastPredictions = predictions.Skip(predictionEpisode.Size).ToArray();
+      for (int i = 0; i < calculatedVars.Length; i++) {
+        var varName = calculatedVars[i];
+        var tree = Content.Trees[i];
+        var dt = new DataTable(varName);
+        var trainingPredValues =
+          Enumerable.Repeat(double.NaN, predictionEpisode.Start)
+          .Concat(trainingPredictions.Select(pi => pi[i]))
+          .Concat(Enumerable.Repeat(double.NaN, ds.Rows - predictionEpisode.Start - trainingPredictions.Length))
+          .ToArray();
+
+        var predRow = new DataRow(varName + " (training)", varName + " (training)", trainingPredValues);
+        dt.Rows.Add(predRow);
+
+        if (targetVars.Contains(varName)) {
+          var targetValues = ds.GetReadOnlyDoubleValues(varName);
+          var targetRow = new DataRow(varName + " (target)", varName + " (target)", targetValues);
+          dt.Rows.Add(targetRow);
+        }
+
+        var forecastPredValues =
+  Enumerable.Repeat(double.NaN, predictionEpisode.End)
+  .Concat(forecastPredictions.Select(pi => pi[i]))
+  .Concat(Enumerable.Repeat(double.NaN, ds.Rows - predictionEpisode.End - forecastPredictions.Length))
+  .ToArray();
+
+        var forecastRow = new DataRow(varName + " (forecast)", varName + " (forecast)", forecastPredValues);
+        dt.Rows.Add(forecastRow);
+
+        var vizProp = new DataTableVisualProperties();
+        dt.VisualProperties = vizProp;
+        var dtv = new DataTableView();
+        dtv.Content = dt;
+        dtv.ShowChartOnly = true;
+        dtv.Dock = System.Windows.Forms.DockStyle.Fill;
+        tableLayoutPanel.Controls.Add(dtv, 0, i);
+      }
+    }
+
+    protected override void OnLockedChanged() {
+      base.OnLockedChanged();
+    }
+
+    private void updateButton_Click(object sender, System.EventArgs e) {
+      UpdatePredictions();
+    }
+
+    private void trackBar_Validated(object sender, EventArgs e) {
+      var start = int.Parse(episodeStartTextbox.Text);
+      if (start == trackBar.Value) return;
+      var end = int.Parse(episodeEndTextbox.Text);
+      var delta = end - start;
+      episodeStartTextbox.Text = (trackBar.Value).ToString();
+      episodeEndTextbox.Text = (trackBar.Value + delta).ToString();
+    }
+
+    private void episodeStartTextbox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int res;
+      e.Cancel = !int.TryParse(episodeStartTextbox.Text, out res);
+    }
+
+    private void episodeStartTextbox_Validated(object sender, EventArgs e) {
+      trackBar.Value = int.Parse(episodeStartTextbox.Text);
+    }
+  }
+}
Index: branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.resx
===================================================================
--- branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.resx	(revision 16399)
+++ branches/2925_AutoDiffForDynamicalModels/HeuristicLab.Problems.DynamicalSystemsModelling/3.3/SolutionView.resx	(revision 16399)
@@ -0,0 +1,123 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <metadata name="animationTimer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
