Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/HeuristicLab.Problems.DataAnalysis.Views-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/HeuristicLab.Problems.DataAnalysis.Views-3.3.csproj	(revision 3407)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/HeuristicLab.Problems.DataAnalysis.Views-3.3.csproj	(revision 3408)
@@ -9,6 +9,6 @@
     <OutputType>Library</OutputType>
     <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>HeuristicLab.Problems.DataAnalysis</RootNamespace>
-    <AssemblyName>HeuristicLab.Problems.DataAnalysis-3.3</AssemblyName>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis.Views-3.3</AssemblyName>
     <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
@@ -85,5 +85,4 @@
     <None Include="Properties\AssemblyInfo.frame" />
     <Compile Include="DataAnalysisProblemDataView.cs">
-      <SubType>UserControl</SubType>
     </Compile>
     <Compile Include="DataAnalysisProblemDataView.Designer.cs">
@@ -98,7 +97,7 @@
       <Name>HeuristicLab.Collections-3.3</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
-      <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project>
-      <Name>HeuristicLab.Common-3.3</Name>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.2\HeuristicLab.Common-3.2.csproj">
+      <Project>{1FC004FC-59AF-4249-B1B6-FF25873A20E4}</Project>
+      <Name>HeuristicLab.Common-3.2</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\HeuristicLab.Core.Views\3.3\HeuristicLab.Core.Views-3.3.csproj">
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.Designer.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.Designer.cs	(revision 3408)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Problem.DataAnalysis.Views {
+  partial class LineChartView {
+    /// <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.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(358, 225);
+      this.chart.TabIndex = 0;
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      // 
+      // QualityLineChart
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.chart);
+      this.Name = "QualityLineChart";
+      this.Size = new System.Drawing.Size(358, 225);
+      this.DragDrop += new System.Windows.Forms.DragEventHandler(this.ModelLineChart_DragDrop);
+      this.DragEnter += new System.Windows.Forms.DragEventHandler(this.ModelLineChart_DragEnter);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.DataVisualization.Charting.Chart chart;
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.cs	(revision 3408)
@@ -0,0 +1,172 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Collections.Specialized;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [View("Line Chart View")]
+  [Content(typeof(DataAnalysisSolution))]
+  public partial class LineChartView : ContentView {
+    
+    public LineChartView()
+      : base() {
+      InitializeComponent();
+      this.Caption = "Line Chart View";
+      //configure axis
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 0;
+
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorY.Interval = 0;      
+    }
+
+    public LineChartView(DataAnalysisSolution dataAnalysisSolution)
+      : this() {
+      
+    }
+
+    private void model_Changed(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Action<object, EventArgs> action = new Action<object, EventArgs>(model_Changed);
+        this.Invoke(action, sender, e);
+      } else {
+        IVisualModel model = (IVisualModel)sender;
+        Series s = this.chart.Series.Single(x => x.Tag == model);
+        s.Points.DataBindY(model.PredictedValues.ToArray());
+        s.LegendText = model.ModelName;
+        this.UpdateStripLines();
+      }
+    }
+
+    protected override void ModelsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
+      base.ModelsCollectionChanged(sender, e);
+      if (InvokeRequired) {
+        Action<object, NotifyCollectionChangedEventArgs> action = new Action<object, NotifyCollectionChangedEventArgs>(ModelsCollectionChanged);
+        this.Invoke(action, sender, e);
+      } else {
+        if (e.Action == NotifyCollectionChangedAction.Remove) {
+          foreach (IVisualModel model in e.OldItems) {
+            if (this.chart.Series.Any(x => x.Tag == model))
+              this.RemoveModel(model);
+          }
+          this.UpdateStripLines();
+        } else if (e.Action == NotifyCollectionChangedAction.Reset)
+          this.RemoveAllModels();
+      }
+    }
+
+    private void AddModel(IVisualModel model) {
+      if (this.targetVariableName != model.TargetVariableName) {
+        this.RemoveAllModels();
+        this.chart.Series.Clear();
+        this.chart.Series.Add(TARGETVARIABLE);
+        this.chart.Series[TARGETVARIABLE].LegendText = model.TargetVariableName;
+        this.chart.Series[TARGETVARIABLE].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[TARGETVARIABLE].Points.DataBindY(model.Dataset.GetVariableValues(model.TargetVariableName));
+        this.targetVariableName = model.TargetVariableName;
+        this.Caption = this.targetVariableName + " Model Line Chart";
+      }
+      string seriesName = model.GetHashCode().ToString();
+      this.chart.Series.Add(seriesName);
+      this.chart.Series[seriesName].Tag = model;
+      this.chart.Series[seriesName].LegendText = model.ModelName;
+      this.chart.Series[seriesName].ChartType = SeriesChartType.FastLine;
+      this.chart.Series[seriesName].Points.DataBindY(model.PredictedValues.ToArray());
+      model.Changed += new EventHandler(model_Changed);
+      this.UpdateStripLines();
+    }
+
+    private void RemoveModel(IVisualModel model) {
+      Series s = this.chart.Series.Single(x => x.Tag == model);
+      this.chart.Series.Remove(s);
+      model.Changed -= new EventHandler(model_Changed);
+    }
+
+    private void RemoveAllModels() {
+      var models = (from s in chart.Series
+                    let m = s.Tag as IVisualModel
+                    where m != null
+                    select m).ToArray(); // select and copy currently displayed models
+      foreach (var m in models) {
+        this.RemoveModel(m);
+      }
+      this.UpdateStripLines();
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = this.chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        if (result.Series.Name != TARGETVARIABLE) {
+          this.RemoveModel(result.Series.Tag as IVisualModel);
+          this.UpdateStripLines();
+        }
+      }
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = this.chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        if (result.Series.Name != TARGETVARIABLE)
+          this.Cursor = Cursors.Hand;
+      } else
+        this.Cursor = Cursors.Default;
+    }
+
+    private void UpdateStripLines() {
+      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
+      IEnumerable<IVisualModel> visualModels = from Series s in this.chart.Series
+                                               where s.Tag is IVisualModel
+                                               select (IVisualModel)s.Tag;
+      if (visualModels.Count() > 0) {
+        IVisualModel model = visualModels.ElementAt(0);
+        if (visualModels.All(x => x.TrainingSamplesStart == model.TrainingSamplesStart && x.TrainingSamplesEnd == model.TrainingSamplesEnd))
+          this.CreateAndAddStripLine("Training", Color.FromArgb(20, Color.Green), model.TrainingSamplesStart, model.TrainingSamplesEnd);
+        if (visualModels.All(x => x.ValidationSamplesStart == model.ValidationSamplesStart && x.ValidationSamplesEnd == model.ValidationSamplesEnd))
+          this.CreateAndAddStripLine("Validation", Color.FromArgb(20, Color.Yellow), model.ValidationSamplesStart, model.ValidationSamplesEnd);
+        if (visualModels.All(x => x.TestSamplesStart == model.TestSamplesStart && x.TestSamplesEnd == model.TestSamplesEnd))
+          this.CreateAndAddStripLine("Test", Color.FromArgb(20, Color.Red), model.TestSamplesStart, model.TestSamplesEnd);
+      }
+    }
+
+    private void CreateAndAddStripLine(string title, Color c, int start, int end) {
+      StripLine stripLine = new StripLine();
+      stripLine.BackColor = c;
+      stripLine.Text = title;
+      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
+      stripLine.StripWidth = end - start;
+      stripLine.IntervalOffset = start;
+      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.resx
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.resx	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/LineChartView.resx	(revision 3408)
@@ -0,0 +1,120 @@
+<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.Designer.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.Designer.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.Designer.cs	(revision 3408)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 ScatterPlotView {
+    /// <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.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+      this.chart = new System.Windows.Forms.DataVisualization.Charting.Chart();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      this.chart.Dock = System.Windows.Forms.DockStyle.Fill;
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Default";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 0);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(527, 392);
+      this.chart.TabIndex = 1;
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(chart_CustomizeLegend);
+      // 
+      // ScatterPlotView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Controls.Add(this.chart);
+      this.Name = "ScatterPlotView";
+      this.AllowDrop = true;
+      this.Size = new System.Drawing.Size(527, 392);
+      this.DragDrop += new System.Windows.Forms.DragEventHandler(this.ScatterPlotView_DragDrop);
+      this.DragEnter += new System.Windows.Forms.DragEventHandler(this.ScatterPlotView_DragEnter);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.DataVisualization.Charting.Chart chart;
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.cs	(revision 3408)
@@ -0,0 +1,249 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.ComponentModel;
+using System.Drawing;
+using System.Data;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using System.Collections.Specialized;
+using HeuristicLab.MainForm;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Problems.DataAnalyis.Views {
+  [View("Scatter Plot View")]
+  [Content(typeof(DataAnalysisSolution))]
+  public partial class ScatterPlotView : ContentView {
+    private const string DEFAULT_CAPTION = "Scatter Plot";
+    private const string ALL_SERIES = "All Samples";
+    private const string TRAINING_SERIES = "Training Samples";
+    private const string validationSeries = "Validation Samples";
+    private const string TEST_SERIES = "Test Samples";
+
+    public ScatterPlotView()
+      : base() {
+      InitializeComponent();
+      this.Caption = DEFAULT_CAPTION;
+
+      this.chart.Series.Add(ALL_SERIES);
+      this.chart.Series[ALL_SERIES].LegendText = ALL_SERIES;
+      this.chart.Series[ALL_SERIES].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.Series.Add(TRAINING_SERIES);
+      this.chart.Series[TRAINING_SERIES].LegendText = TRAINING_SERIES;
+      this.chart.Series[TRAINING_SERIES].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.Series.Add(validationSeries);
+      this.chart.Series[validationSeries].LegendText = validationSeries;
+      this.chart.Series[validationSeries].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.Series.Add(TEST_SERIES);
+      this.chart.Series[TEST_SERIES].LegendText = TEST_SERIES;
+      this.chart.Series[TEST_SERIES].ChartType = SeriesChartType.FastPoint;
+
+      this.chart.TextAntiAliasingQuality = TextAntiAliasingQuality.High;
+      this.chart.AxisViewChanged += new EventHandler<System.Windows.Forms.DataVisualization.Charting.ViewEventArgs>(chart_AxisViewChanged);
+
+      //configure axis                  
+      this.chart.ChartAreas[0].AxisX.Title = "Estimated Values";
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 0;
+      this.chart.ChartAreas[0].CursorY.Interval = 0;
+
+      this.chart.ChartAreas[0].AxisY.Title = "Target Values";
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
+    }
+
+    public ScatterPlotView(IVisualModel visualModel)
+      : this() {
+      this.VisualModel = visualModel;
+    }
+
+    private IVisualModel visualModel;
+    public IVisualModel VisualModel {
+      get { return this.visualModel; }
+      private set {
+        if (this.visualModel != null) {
+          this.visualModel.Changed -= new EventHandler(model_Changed);                 
+        }
+        this.visualModel = value;
+        if (this.visualModel != null) {
+          this.Caption = this.visualModel.ModelName + " " + DEFAULT_CAPTION;
+          this.visualModel.Changed += new EventHandler(model_Changed);
+          this.UpdateSeries();
+          if (!this.chart.Series.Any(s => s.Points.Count > 0))
+            this.ToggleSeriesData(this.chart.Series[TRAINING_SERIES]);
+        } else {
+          this.Caption = DEFAULT_CAPTION;
+          this.ClearChart();
+        }
+      }
+    }
+
+    private void UpdateSeries() {
+      if (this.chart.Series[ALL_SERIES].Points.Count > 0)
+        this.chart.Series[ALL_SERIES].Points.DataBindXY(this.visualModel.PredictedValues.ToArray(), "",
+          this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName), "");
+      if (this.chart.Series[TRAINING_SERIES].Points.Count > 0)
+        this.chart.Series[TRAINING_SERIES].Points.DataBindXY(this.visualModel.PredictedTrainingValues.ToArray(), "",
+          this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.TrainingSamplesStart, this.visualModel.TrainingSamplesEnd), "");
+      if (this.chart.Series[validationSeries].Points.Count > 0)
+        this.chart.Series[validationSeries].Points.DataBindXY(this.visualModel.PredictedValidationValues.ToArray(), "",
+          this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.ValidationSamplesStart, this.visualModel.ValidationSamplesEnd), "");
+      if (this.chart.Series[TEST_SERIES].Points.Count > 0)
+        this.chart.Series[TEST_SERIES].Points.DataBindXY(this.visualModel.PredictedTestValues.ToArray(), "",
+          this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.TestSamplesStart, this.visualModel.TestSamplesEnd), "");
+
+      double x = this.visualModel.PredictedValues.Max();
+      double y = this.visualModel.Dataset.GetMaximum(this.visualModel.TargetVariableName);
+      double max = x > y ? x : y;
+      x = this.visualModel.PredictedValues.Min();
+      y = this.visualModel.Dataset.GetMinimum(this.visualModel.TargetVariableName);
+      double min = x < y ? x : y;
+
+      max = Math.Ceiling(max) * 1.2;
+      min = Math.Floor(min) * 0.8;
+
+      this.chart.ChartAreas[0].AxisX.Maximum = max;
+      this.chart.ChartAreas[0].AxisX.Minimum = min;
+      this.chart.ChartAreas[0].AxisY.Maximum = max;
+      this.chart.ChartAreas[0].AxisY.Minimum = min;
+    }
+
+    private void ClearChart() {
+      this.chart.Series[ALL_SERIES].Points.Clear();
+      this.chart.Series[TRAINING_SERIES].Points.Clear();
+      this.chart.Series[validationSeries].Points.Clear();
+      this.chart.Series[TEST_SERIES].Points.Clear();
+    }
+
+
+    private void model_Changed(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Action<object, EventArgs> action = new Action<object, EventArgs>(model_Changed);
+        this.Invoke(action, sender, e);
+      } else {
+        this.Caption = this.visualModel.ModelName + " " + DEFAULT_CAPTION;
+        this.UpdateSeries();
+      }
+    }
+
+    protected override void OnClosed(FormClosedEventArgs e) {
+      base.OnClosed( e);
+      this.VisualModel = null;
+    }
+
+    protected override void ModelsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) {
+      if (InvokeRequired) {
+        Action<object, NotifyCollectionChangedEventArgs> action = new Action<object, NotifyCollectionChangedEventArgs>(ModelsCollectionChanged);
+        this.Invoke(action, sender, e);
+      } else {
+        if (e.Action == NotifyCollectionChangedAction.Remove) {
+          if (e.OldItems.Contains(this.visualModel))
+            this.VisualModel = null;
+        }
+        if(e.Action == NotifyCollectionChangedAction.Reset)
+          this.VisualModel = null;
+      }
+    }  
+
+    private void ToggleSeriesData(Series series) {
+      if (series.Points.Count > 0) {  //checks if series is shown
+        if (this.chart.Series.Any(s => s != series && s.Points.Count > 0)) {
+          series.Points.Clear();    
+        }
+      } else if (this.visualModel != null) {
+        IEnumerable<double> predictedValues = null;
+        IEnumerable<double> targetValues = null;
+        switch (series.Name) {
+          case ALL_SERIES:
+            predictedValues = this.visualModel.PredictedValues;
+            targetValues = this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName);
+            break;
+          case TRAINING_SERIES:
+            predictedValues = this.visualModel.PredictedTrainingValues;
+            targetValues = this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.TrainingSamplesStart, this.visualModel.TrainingSamplesEnd);
+            break;
+          case validationSeries:
+            predictedValues = this.visualModel.PredictedValidationValues;
+            targetValues = this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.ValidationSamplesStart, this.visualModel.ValidationSamplesEnd);
+            break;
+          case TEST_SERIES:
+            predictedValues = this.visualModel.PredictedTestValues;
+            targetValues = this.visualModel.Dataset.GetVariableValues(this.visualModel.TargetVariableName, this.visualModel.TestSamplesStart, this.visualModel.TestSamplesEnd);
+            break;
+        }
+        series.Points.DataBindXY(predictedValues.ToArray(), "", targetValues, "");
+        this.chart.Legends[series.Legend].ForeColor = Color.Black;
+      }
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        this.ToggleSeriesData(result.Series);
+      }
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        this.Cursor = Cursors.Hand;
+      else
+        this.Cursor = Cursors.Default;
+    }
+
+    private void chart_AxisViewChanged(object sender, System.Windows.Forms.DataVisualization.Charting.ViewEventArgs e) {
+      this.chart.ChartAreas[0].AxisX.ScaleView.Size = e.NewSize;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Size = e.NewSize;
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[ALL_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[TRAINING_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[validationSeries].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[TEST_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+
+
+    private void ScatterPlotView_DragDrop(object sender, DragEventArgs e) {
+      IVisualModel model = this.ExtractModel(e.Data);
+      if (model != null) {
+        this.VisualModel = model;
+      }
+    }
+
+    private void ScatterPlotView_DragEnter(object sender, DragEventArgs e) {
+      IVisualModel model = this.ExtractModel(e.Data);
+      if (model != null)
+        e.Effect = DragDropEffects.Link;
+      else
+        e.Effect = DragDropEffects.None;
+    }
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.resx
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.resx	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis.Views/3.3/ScatterPlotView.resx	(revision 3408)
@@ -0,0 +1,120 @@
+<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/DataAnalysisSolution.cs	(revision 3408)
@@ -0,0 +1,113 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a solution for a data analysis problem which can be visualized in the GUI.
+  /// </summary>
+  [Item("DataAnalysisSolution", "Represents a solution for a data analysis problem which can be visualized in the GUI.")]
+  [StorableClass]
+  public sealed class DataAnalysisSolution : Item {
+    [Storable]
+    private IPredictor predictor;
+    public IPredictor Predictor {
+      get { return predictor; }
+      set {
+        if (predictor != value) {
+          predictor = value;
+          OnPredictorChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private DataAnalysisProblemData problemData;
+    public DataAnalysisProblemData ProblemData {
+      get { return problemData; }
+      set {
+        if (problemData != value) {
+          if (problemData != null) DeregisterProblemDataEvents();
+          problemData = value;
+          if (problemData != null) RegisterProblemDataEvents();
+          OnProblemDataChanged();
+        }
+      }
+    }
+    
+    public DataAnalysisSolution() : base() { }
+    public DataAnalysisSolution(DataAnalysisProblemData problemData, IPredictor predictor)
+      : this() {
+      this.problemData = problemData;
+      this.predictor = predictor;
+      Initialize();
+    }
+    [StorableConstructor]
+    private DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void Initialize() {
+      if (problemData != null) RegisterProblemDataEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      DataAnalysisSolution clone = new DataAnalysisSolution();
+      cloner.RegisterClonedObject(this, clone);
+      clone.ReadOnlyView = ReadOnlyView;
+      clone.predictor = (IPredictor)cloner.Clone(predictor);
+      clone.problemData = problemData;
+      clone.Initialize();
+      return clone;
+    }
+
+    #region Events
+    public event EventHandler PredictorChanged;
+    private void OnPredictorChanged() {
+      var changed = PredictorChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+    public event EventHandler ProblemDataChanged;
+    private void OnProblemDataChanged() {
+      var changed = ProblemDataChanged;
+      if (changed != null)
+        changed(this, EventArgs.Empty);
+    }
+
+    private void RegisterProblemDataEvents() {
+      ProblemData.DatasetChanged += new EventHandler(ProblemData_DataSetChanged);
+    }
+    private void DeregisterProblemDataEvents() {
+      ProblemData.DatasetChanged += new EventHandler(ProblemData_DataSetChanged);
+    }
+
+    private void ProblemData_DataSetChanged(object sender, EventArgs e) {
+      OnProblemDataChanged();
+    }
+    #endregion
+  }
+}
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 3407)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/HeuristicLab.Problems.DataAnalysis-3.3.csproj	(revision 3408)
@@ -84,4 +84,5 @@
     <None Include="HeuristicLabProblemsDataAnalysisPlugin.cs.frame" />
     <None Include="Properties\AssemblyInfo.frame" />
+    <Compile Include="DataAnalysisSolution.cs" />
     <Compile Include="CsvFileParser.cs" />
     <Compile Include="DataAnalysisProblem.cs" />
@@ -92,4 +93,5 @@
     <Compile Include="Evaluators\SimpleMSEEvaluator.cs" />
     <Compile Include="HeuristicLabProblemsDataAnalysisPlugin.cs" />
+    <Compile Include="Interfaces\IPredictor.cs" />
     <Compile Include="MatrixExtensions.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
Index: trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IPredictor.cs
===================================================================
--- trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IPredictor.cs	(revision 3408)
+++ trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Interfaces/IPredictor.cs	(revision 3408)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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 System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Operators;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IPredictor : IDeepCloneable {
+    double Estimate(double[] xs);
+  }
+}
