Index: branches/HeuristicLab.Classification/HeuristicLab.Classification.sln
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Classification.sln	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Classification.sln	(revision 4366)
@@ -3,8 +3,13 @@
 # Visual Studio 2010
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Classification", "HeuristicLab.Classification\HeuristicLab.Classification.csproj", "{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}"
+	ProjectSection(ProjectDependencies) = postProject
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E} = {D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}
+	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Classification", "HeuristicLab.Problems.DataAnalysis.Classification\3.3\HeuristicLab.Problems.DataAnalysis.Classification.csproj", "{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{08118029-0DA6-4105-BF1F-9453C0F3AC75}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Classification.Views", "HeuristicLab.Problems.DataAnalysis.Classification.Views\3.3\HeuristicLab.Problems.DataAnalysis.Classification.Views.csproj", "{7F038E9A-B91E-4F49-8C27-D47BC86F1220}"
 EndProject
 Global
@@ -15,15 +20,41 @@
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
 		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
 		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|x64.ActiveCfg = Debug|x64
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|x64.Build.0 = Debug|x64
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|x86.ActiveCfg = Debug|x86
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Debug|x86.Build.0 = Debug|x86
 		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Release|x64.ActiveCfg = Release|Any CPU
+		{3AB5A7E5-9F0C-4920-B18D-E06B9577618C}.Release|x86.ActiveCfg = Release|Any CPU
 		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|x64.ActiveCfg = Debug|x64
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|x64.Build.0 = Debug|x64
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|x86.ActiveCfg = Debug|x86
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Debug|x86.Build.0 = Debug|x86
 		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Release|x64.ActiveCfg = Release|Any CPU
+		{D35FD6DB-D704-4BEA-BDAE-C40ABFB5B13E}.Release|x86.ActiveCfg = Release|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|x64.ActiveCfg = Debug|x64
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|x64.Build.0 = Debug|x64
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|x86.ActiveCfg = Debug|x86
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Debug|x86.Build.0 = Debug|x86
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Release|Any CPU.Build.0 = Release|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Release|x64.ActiveCfg = Release|Any CPU
+		{7F038E9A-B91E-4F49-8C27-D47BC86F1220}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/HeuristicLab.Classification/HeuristicLab.Classification/HeuristicLab.Classification.csproj
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Classification/HeuristicLab.Classification.csproj	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Classification/HeuristicLab.Classification.csproj	(revision 4366)
@@ -32,4 +32,68 @@
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.Classification.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.Classification.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.Classification.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.Classification.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>false</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
Index: branches/HeuristicLab.Classification/HeuristicLab.Classification/UpdateLocalInstallation.cmd
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Classification/UpdateLocalInstallation.cmd	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Classification/UpdateLocalInstallation.cmd	(revision 4366)
@@ -2,2 +2,3 @@
 
 copy "%SolutionDir%\HeuristicLab.Problems.DataAnalysis.Classification\3.3\%Outdir%\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll" "%target%"
+copy "%SolutionDir%\HeuristicLab.Problems.DataAnalysis.Classification.Views\3.3\%Outdir%\HeuristicLab.Problems.DataAnalysis.Classification.Views-3.3.dll" "%target%"
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/ClassificationProblemData.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/ClassificationProblemData.cs	(revision 4366)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/ClassificationProblemData.cs	(revision 4366)
@@ -0,0 +1,181 @@
+﻿#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.IO;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis.Classification {
+  [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
+  [StorableClass]
+  public class ClassificationProblemData : DataAnalysisProblemData {
+    private const int MaximumClasses = 20;
+    private const string ClassNamesParameterName = "ClassNames";
+    private const string MisclassificationMatrixParameterName = "MisClassificationMatrix";
+
+    public StringArray ClassNames {
+      get { return ClassNamesParameter.Value; }
+      protected set { ClassNamesParameter.Value = value; }
+    }
+    public IValueParameter<StringArray> ClassNamesParameter {
+      get { return (IValueParameter<StringArray>)Parameters[ClassNamesParameterName]; }
+    }
+
+    public DoubleMatrix MisclassificationMatrix {
+      get { return MisclassificationMatrixParameter.Value; }
+      protected set { MisclassificationMatrixParameter.Value = value; }
+    }
+    public IValueParameter<DoubleMatrix> MisclassificationMatrixParameter {
+      get { return (IValueParameter<DoubleMatrix>)Parameters[MisclassificationMatrixParameterName]; }
+    }
+
+    [Storable]
+    private List<double> sortedClassValues;
+    public IEnumerable<double> SortedClassValues {
+      get { return sortedClassValues; }
+    }
+    public int NumberOfClasses {
+      get { return sortedClassValues.Count; }
+    }
+
+    public ClassificationProblemData()
+      : base() {
+      Parameters.Add(new ValueParameter<StringArray>(ClassNamesParameterName, "An array of the names for all class values."));
+      Parameters.Add(new ValueParameter<DoubleMatrix>(MisclassificationMatrixParameterName, "A matrix that describles the penalties for misclassifaction between the single classes."));
+      sortedClassValues = new List<double>();
+
+      RegisterParameterEvents();
+      UpdateClassValues();
+    }
+
+    [StorableConstructor]
+    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserializationHook() {
+      RegisterParameterEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      ClassificationProblemData clone = (ClassificationProblemData)base.Clone(cloner);
+      clone.RegisterParameterEvents();
+      clone.UpdateClassValues();
+      return clone;
+    }
+
+    protected override void OnProblemDataChanged(System.EventArgs e) {
+      if (!suppressEvents) {
+        UpdateClassValues();
+        base.OnProblemDataChanged(e);
+      }
+    }
+
+    public override void ImportFromFile(string fileName) {
+      var csvFileParser = new CsvFileParser();
+      csvFileParser.Parse(fileName);
+      suppressEvents = true;
+      Name = "Data imported from " + Path.GetFileName(fileName);
+      Dataset = new Dataset(csvFileParser.VariableNames, csvFileParser.Values);
+      Dataset.Name = Path.GetFileName(fileName);
+      var variableNames = Dataset.VariableNames.Select(x => new StringValue(x).AsReadOnly()).ToList();
+      var validTargetVariables = variableNames.Select(variable => new { Variable = variable, DistinctValues = Dataset.GetVariableValues(variable.Value, 0, 50).Distinct().Count() })
+         .OrderBy(x => x.DistinctValues).Where(x => x.DistinctValues <= MaximumClasses).Select(x => x.Variable);
+      if (!validTargetVariables.Any())
+        throw new ArgumentException("Import of classification problem data was not successfull, because no target variable was found." +
+          " A target varialbe must have at most " + MaximumClasses + " distinct values to be applicable to classification.");
+
+      ((ConstrainedValueParameter<StringValue>)TargetVariableParameter).ValidValues.Clear();
+      foreach (var variableName in validTargetVariables)
+        ((ConstrainedValueParameter<StringValue>)TargetVariableParameter).ValidValues.Add(variableName);
+      TargetVariable = validTargetVariables.FirstOrDefault();
+
+      InputVariables = new CheckedItemList<StringValue>(variableNames).AsReadOnly();
+      InputVariables.SetItemCheckedState(validTargetVariables.First(), false);
+      int middle = (int)(csvFileParser.Rows * 0.5);
+      TrainingSamplesStart = new IntValue(0);
+      TrainingSamplesEnd = new IntValue(middle);
+      TestSamplesStart = new IntValue(middle);
+      TestSamplesEnd = new IntValue(csvFileParser.Rows);
+      suppressEvents = false;
+      OnProblemDataChanged(EventArgs.Empty);
+    }
+
+    private void UpdateClassValues() {
+      sortedClassValues = Dataset.GetVariableValues(TargetVariable.Value).Distinct().ToList();
+      sortedClassValues.Sort();
+      ResetMisclassificationMatrix();
+      UpdateClassNames();
+    }
+
+    private void UpdateClassNames() {
+      if (ClassNames != null) DeregisterParameterValueEvents();
+      StringArray array = new StringArray(NumberOfClasses);
+      int i = 0;
+      foreach (double classValue in SortedClassValues) {
+        array[i] = "Class " + classValue;
+        i++;
+      }
+      ClassNames = array;
+      RegisterParameterValueEvents();
+    }
+
+    private void RegisterParameterEvents() {
+      ClassNamesParameter.ValueChanged += new EventHandler(ClassNamesChanged);
+    }
+    private void RegisterParameterValueEvents() {
+      ClassNames.ItemChanged += new EventHandler<EventArgs<int>>(ClassNamesChanged);
+    }
+    private void DeregisterParameterValueEvents() {
+      ClassNames.ItemChanged -= new EventHandler<EventArgs<int>>(ClassNamesChanged);
+    }
+
+    private void ClassNamesChanged(object sender, EventArgs e) {
+      UpdateMisclassifciationMatrixHeaders();
+    }
+
+    private void ResetMisclassificationMatrix() {
+      double[,] matrix = new double[NumberOfClasses, NumberOfClasses];
+      for (int i = 0; i < NumberOfClasses; i++) {
+        for (int j = 0; j < NumberOfClasses; j++)
+          if (i != j) matrix[i, j] = 1;
+      }
+
+      if (MisclassificationMatrix == null)
+        MisclassificationMatrix = new DoubleMatrix(matrix);
+      if (MisclassificationMatrix.Rows != NumberOfClasses)
+        MisclassificationMatrix = new DoubleMatrix(matrix);
+      if (MisclassificationMatrix.Columns != NumberOfClasses)
+        MisclassificationMatrix = new DoubleMatrix(matrix);
+    }
+
+    private void UpdateMisclassifciationMatrixHeaders() {
+      MisclassificationMatrix.RowNames = ClassNames;
+      MisclassificationMatrix.ColumnNames = ClassNames;
+    }
+
+
+  }
+}
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLab.Problems.DataAnalysis.Classification.csproj
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLab.Problems.DataAnalysis.Classification.csproj	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLab.Problems.DataAnalysis.Classification.csproj	(revision 4366)
@@ -38,34 +38,102 @@
     <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x64\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>bin\x64\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>bin\x86\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Debug\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>bin\x86\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <CodeAnalysisLogFile>bin\Release\HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
+    <CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
+    <CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRuleSetDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
+    <CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
+    <CodeAnalysisRuleDirectories>;c:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
+    <CodeAnalysisIgnoreBuiltInRules>false</CodeAnalysisIgnoreBuiltInRules>
+  </PropertyGroup>
   <ItemGroup>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
     <Reference Include="HeuristicLab.Collections-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Collections-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Collections-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Common-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.2.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=AMD64" />
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.2.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
     <Reference Include="HeuristicLab.Core-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Data-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Data-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Data-3.3.dll</HintPath>
     </Reference>
-    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=AMD64" />
-    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=AMD64" />
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=x86" />
     <Reference Include="HeuristicLab.Optimization-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Optimization-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Parameters-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Parameters-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Persistence-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
     </Reference>
     <Reference Include="HeuristicLab.Problems.DataAnalysis-3.3">
-      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis-3.3.dll</HintPath>
+      <HintPath>c:\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Regression-3.3">
+      <HintPath>..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Problems.DataAnalysis.Regression-3.3.dll</HintPath>
     </Reference>
     <Reference Include="System" />
@@ -78,10 +146,15 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="ClassificationProblemData.cs" />
+    <Compile Include="HeuristicLabProblemsDataAnalysisClassificationPlugin.cs" />
+    <Compile Include="Interfaces\IClassificationSolution.cs" />
     <Compile Include="SingleObjectiveClassificationProblem.cs" />
     <Compile Include="ProblemBase\Problem.cs" />
     <Compile Include="Interfaces\ISymbolicClassificationEvaluator.cs" />
-    <Compile Include="HeuristicLabProblemsDataAnalysisClassifcationPlugin.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ProblemBase\SingleObjectiveProblem.cs" />
+    <Compile Include="Interfaces\ISymbolicClassificationAnalyzer.cs" />
+    <Compile Include="Symbolic\Analyzer\ValidationBestSymbolicClassificationSolutionAnalyzer.cs" />
+    <Compile Include="Symbolic\SymbolicClassificationSolution.cs" />
     <Compile Include="Symbolic\SingleObjectiveSymbolicClassificationEvaluator.cs" />
     <Compile Include="Symbolic\SymbolicClassificationMeanSquaredErrorEvaluator.cs" />
@@ -93,4 +166,5 @@
     <None Include="Properties\AssemblyInfo.frame" />
   </ItemGroup>
+  <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>
@@ -101,5 +175,5 @@
 
 call PreBuildEvent.cmd
-SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25HeuristicLabProblemsDataAnalysisClassificationPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisClassifcationPlugin.cs"</PreBuildEvent>
+SubWCRev "%25ProjectDir%25\" "%25ProjectDir%25HeuristicLabProblemsDataAnalysisClassificationPlugin.cs.frame" "%25ProjectDir%25\HeuristicLabProblemsDataAnalysisClassificationPlugin.cs"</PreBuildEvent>
   </PropertyGroup>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLabProblemsDataAnalysisClassificationPlugin.cs.frame
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLabProblemsDataAnalysisClassificationPlugin.cs.frame	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/HeuristicLabProblemsDataAnalysisClassificationPlugin.cs.frame	(revision 4366)
@@ -23,7 +23,4 @@
 
 namespace HeuristicLab.Problems.DataAnalysis.Classification {
-  /// <summary>
-  /// Plugin class for HeuristicLab.Algorithms.LocalSearch plugin.
-  /// </summary>
   [Plugin("HeuristicLab.Problems.DataAnalysis.Classification", "3.3.0.$WCREV$")]
   [PluginFile("HeuristicLab.Problems.DataAnalysis.Classification-3.3.dll", PluginFileType.Assembly)]
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/IClassificationSolution.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/IClassificationSolution.cs	(revision 4366)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/IClassificationSolution.cs	(revision 4366)
@@ -0,0 +1,26 @@
+﻿#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 HeuristicLab.Core;
+namespace HeuristicLab.Problems.DataAnalysis.Classification {
+  public interface IClassificationSolution : IItem {
+  }
+}
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationAnalyzer.cs	(revision 4366)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationAnalyzer.cs	(revision 4366)
@@ -0,0 +1,35 @@
+﻿#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 HeuristicLab.Core;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+// This interface is exactly the same as ISymbolicRegressionAnalyzer
+// consider creating a base interface for both analyzer
+
+namespace HeuristicLab.Problems.DataAnalysis.Classification {
+  public interface ISymbolicClassificationAnalyzer : ISymbolicExpressionTreeAnalyzer {
+    ILookupParameter<ResultCollection> ResultsParameter { get; }
+  }
+}
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationEvaluator.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationEvaluator.cs	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Interfaces/ISymbolicClassificationEvaluator.cs	(revision 4366)
@@ -30,5 +30,5 @@
     ILookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter { get; }
     ILookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter { get; }
-    ILookupParameter<DataAnalysisProblemData> RegressionProblemDataParameter { get; }
+    ILookupParameter<ClassificationProblemData> RegressionProblemDataParameter { get; }
     IValueLookupParameter<IntValue> SamplesStartParameter { get; }
     IValueLookupParameter<IntValue> SamplesEndParameter { get; }
@@ -39,5 +39,5 @@
     double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree tree,
           double lowerEstimationLimit, double upperEstimationLimit,
-          Dataset dataset, string targetVariable, IEnumerable<int> rows);
+          Dataset dataset, string targetVariable, IEnumerable<double> sortedClassValues, IEnumerable<int> rows);
   }
 }
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/SingleObjectiveClassificationProblem.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/SingleObjectiveClassificationProblem.cs	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/SingleObjectiveClassificationProblem.cs	(revision 4366)
@@ -35,8 +35,8 @@
     private const string ClassificationProblemDataParameterName = "ClassificationProblemData";
 
-    public ValueParameter<DataAnalysisProblemData> ClassificationProblemDataParameter {
-      get { return (ValueParameter<DataAnalysisProblemData>)Parameters[ClassificationProblemDataParameterName]; }
+    public IValueParameter<ClassificationProblemData> ClassificationProblemDataParameter {
+      get { return (IValueParameter<ClassificationProblemData>)Parameters[ClassificationProblemDataParameterName]; }
     }
-    public DataAnalysisProblemData ClassificationProblemData {
+    public ClassificationProblemData ClassificationProblemData {
       get { return ClassificationProblemDataParameter.Value; }
       set { ClassificationProblemDataParameter.Value = value; }
@@ -47,6 +47,6 @@
     public SingleObjectiveClassificationProblem()
       : base() {
-      Parameters.Add(new ValueParameter<DataAnalysisProblemData>(ClassificationProblemDataParameterName, "The data set, target variable and input variables of the data analysis problem."));
-      ClassificationProblemData = new DataAnalysisProblemData();
+      Parameters.Add(new ValueParameter<ClassificationProblemData>(ClassificationProblemDataParameterName, "The data set, target variable and input variables of the data analysis problem."));
+      ClassificationProblemData = new ClassificationProblemData();
       RegisterParameterEvents();
       RegisterParameterValueEvents();
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/Analyzer/ValidationBestSymbolicClassificationSolutionAnalyzer.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/Analyzer/ValidationBestSymbolicClassificationSolutionAnalyzer.cs	(revision 4366)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/Analyzer/ValidationBestSymbolicClassificationSolutionAnalyzer.cs	(revision 4366)
@@ -0,0 +1,235 @@
+﻿#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.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic;
+
+namespace HeuristicLab.Problems.DataAnalysis.Classification {
+  [Item("ValidationBestSymbolicClassificationSolutionAnalyzer", "An operator that analyzes the validation best symbolic classification solution.")]
+  [StorableClass]
+  public class ValidationBestSymbolicClassificationSolutionAnalyzer : SingleSuccessorOperator, ISymbolicClassificationAnalyzer {
+    private const string MaximizationParameterName = "Maximization";
+    private const string GenerationsParameterName = "Generations";
+    private const string RandomParameterName = "Random";
+    private const string SymbolicExpressionTreeParameterName = "SymbolicExpressionTree";
+    private const string SymbolicExpressionTreeInterpreterParameterName = "SymbolicExpressionTreeInterpreter";
+
+    private const string ClassificationProblemDataParameterName = "ClassificationProblemData";
+    private const string EvaluatorParameterName = "Evaluator";
+    private const string ValidationSamplesStartParameterName = "SamplesStart";
+    private const string ValidationSamplesEndParameterName = "SamplesEnd";
+    private const string RelativeNumberOfEvaluatedSamplesParameterName = "RelativeNumberOfEvaluatedSamples";
+    private const string UpperEstimationLimitParameterName = "UpperEstimationLimit";
+    private const string LowerEstimationLimitParameterName = "LowerEstimationLimit";
+
+    private const string ResultsParameterName = "Results";
+    private const string BestValidationQualityParameterName = "BestValidationQuality";
+    private const string BestValidationSolutionParameterName = "BestValidationSolution";
+
+    #region parameter properties
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters[MaximizationParameterName]; }
+    }
+    public ILookupParameter<IntValue> GenerationsParameter {
+      get { return (ILookupParameter<IntValue>)Parameters[GenerationsParameterName]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters[RandomParameterName]; }
+    }
+    public ScopeTreeLookupParameter<SymbolicExpressionTree> SymbolicExpressionTreeParameter {
+      get { return (ScopeTreeLookupParameter<SymbolicExpressionTree>)Parameters[SymbolicExpressionTreeParameterName]; }
+    }
+    public IValueLookupParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (IValueLookupParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    }
+
+    public ILookupParameter<ClassificationProblemData> ClassificationProblemDataParameter {
+      get { return (ILookupParameter<ClassificationProblemData>)Parameters[ClassificationProblemDataParameterName]; }
+    }
+    public ILookupParameter<ISymbolicClassificationEvaluator> EvaluatorParameter {
+      get { return (ILookupParameter<ISymbolicClassificationEvaluator>)Parameters[EvaluatorParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> ValidationSamplesStartParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ValidationSamplesStartParameterName]; }
+    }
+    public IValueLookupParameter<IntValue> ValidationSamplesEndParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters[ValidationSamplesEndParameterName]; }
+    }
+    public IValueParameter<PercentValue> RelativeNumberOfEvaluatedSamplesParameter {
+      get { return (IValueParameter<PercentValue>)Parameters[RelativeNumberOfEvaluatedSamplesParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    }
+    public IValueLookupParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueLookupParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    }
+
+    public ILookupParameter<ResultCollection> ResultsParameter {
+      get { return (ILookupParameter<ResultCollection>)Parameters[ResultsParameterName]; }
+    }
+    public ILookupParameter<DoubleValue> BestValidationQualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters[BestValidationQualityParameterName]; }
+    }
+    public ILookupParameter<SymbolicClassificationSolution> BestValidationSolutionParameter {
+      get { return (ILookupParameter<SymbolicClassificationSolution>)Parameters[BestValidationSolutionParameterName]; }
+    }
+    #endregion
+    #region properties
+    public BoolValue Maximization {
+      get { return MaximizationParameter.ActualValue; }
+    }
+    public IntValue Generations {
+      get { return GenerationsParameter.ActualValue; }
+    }
+    public IRandom Random {
+      get { return RandomParameter.ActualValue; }
+    }
+    public ItemArray<SymbolicExpressionTree> SymbolicExpressionTree {
+      get { return SymbolicExpressionTreeParameter.ActualValue; }
+    }
+    public ISymbolicExpressionTreeInterpreter SymbolicExpressionTreeInterpreter {
+      get { return SymbolicExpressionTreeInterpreterParameter.ActualValue; }
+    }
+
+    public ClassificationProblemData ClassificationProblemData {
+      get { return ClassificationProblemDataParameter.ActualValue; }
+    }
+    public ISymbolicClassificationEvaluator Evaluator {
+      get { return EvaluatorParameter.ActualValue; }
+    }
+    public IntValue ValidiationSamplesStart {
+      get { return ValidationSamplesStartParameter.ActualValue; }
+    }
+    public IntValue ValidationSamplesEnd {
+      get { return ValidationSamplesEndParameter.ActualValue; }
+    }
+    public PercentValue RelativeNumberOfEvaluatedSamples {
+      get { return RelativeNumberOfEvaluatedSamplesParameter.Value; }
+    }
+    public DoubleValue UpperEstimationLimit {
+      get { return UpperEstimationLimitParameter.ActualValue; }
+    }
+    public DoubleValue LowerEstimationLimit {
+      get { return LowerEstimationLimitParameter.ActualValue; }
+    }
+
+    public ResultCollection Results {
+      get { return ResultsParameter.ActualValue; }
+    }
+    public DoubleValue BestValidationQuality {
+      get { return BestValidationQualityParameter.ActualValue; }
+      protected set { BestValidationQualityParameter.ActualValue = value; }
+    }
+    public SymbolicClassificationSolution BestValidationSolution {
+      get { return BestValidationSolutionParameter.ActualValue; }
+      protected set { BestValidationSolutionParameter.ActualValue = value; }
+    }
+    #endregion
+
+    public ValidationBestSymbolicClassificationSolutionAnalyzer()
+      : base() {
+      Parameters.Add(new LookupParameter<BoolValue>(MaximizationParameterName, "The direction of optimization."));
+      Parameters.Add(new LookupParameter<IntValue>(GenerationsParameterName, "The number of generations calculated so far."));
+      Parameters.Add(new LookupParameter<IRandom>(RandomParameterName, "The random generator to use."));
+      Parameters.Add(new ScopeTreeLookupParameter<SymbolicExpressionTree>(SymbolicExpressionTreeParameterName, "The symbolic expression trees to analyze."));
+      Parameters.Add(new ValueLookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used for the analysis of symbolic expression trees."));
+
+      Parameters.Add(new LookupParameter<ClassificationProblemData>(ClassificationProblemDataParameterName, "The problem data for which the symbolic expression tree is a solution."));
+      Parameters.Add(new LookupParameter<ISymbolicClassificationEvaluator>(EvaluatorParameterName, "The evaluator which should be used to evaluate the solution on the validation set."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesStartParameterName, "The first index of the validation partition of the data set."));
+      Parameters.Add(new ValueLookupParameter<IntValue>(ValidationSamplesEndParameterName, "The last index of the validation partition of the data set."));
+      Parameters.Add(new ValueParameter<PercentValue>(RelativeNumberOfEvaluatedSamplesParameterName, "The relative number of samples of the dataset partition, which should be randomly chosen for evaluation between the start and end index.", new PercentValue(1)));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(UpperEstimationLimitParameterName, "The upper estimation limit that was set for the evaluation of the symbolic expression trees."));
+      Parameters.Add(new ValueLookupParameter<DoubleValue>(LowerEstimationLimitParameterName, "The lower estimation limit that was set for the evaluation of the symbolic expression trees."));
+
+      Parameters.Add(new ValueLookupParameter<ResultCollection>(ResultsParameterName, "The results collection where the analysis values should be stored."));
+      Parameters.Add(new LookupParameter<DoubleValue>(BestValidationQualityParameterName, "The validation quality of the best solution in the current run."));
+      Parameters.Add(new LookupParameter<SymbolicClassificationSolution>(BestValidationSolutionParameterName, "The best solution on the validation data found in the current run."));
+    }
+
+    [StorableConstructor]
+    private ValidationBestSymbolicClassificationSolutionAnalyzer(bool deserializing) : base(deserializing) { }
+
+    public override IOperation Apply() {
+      var trees = SymbolicExpressionTree;
+      string targetVariable = ClassificationProblemData.TargetVariable.Value;
+
+      // select a random subset of rows in the validation set
+      int validationStart = ValidiationSamplesStart.Value;
+      int validationEnd = ValidationSamplesEnd.Value;
+      int seed = Random.Next();
+      int count = (int)((validationEnd - validationStart) * RelativeNumberOfEvaluatedSamples.Value);
+      if (count == 0) count = 1;
+      IEnumerable<int> rows = RandomEnumerable.SampleRandomNumbers(seed, validationStart, validationEnd, count);
+
+      double upperEstimationLimit = UpperEstimationLimit != null ? UpperEstimationLimit.Value : double.PositiveInfinity;
+      double lowerEstimationLimit = LowerEstimationLimit != null ? LowerEstimationLimit.Value : double.NegativeInfinity;
+
+      double bestQuality = Maximization.Value ? double.NegativeInfinity : double.PositiveInfinity;
+      SymbolicExpressionTree bestTree = null;
+
+      foreach (var tree in trees) {
+        double quality = Evaluator.Evaluate(SymbolicExpressionTreeInterpreter, tree,
+          lowerEstimationLimit, upperEstimationLimit, ClassificationProblemData.Dataset,
+          targetVariable, ClassificationProblemData.SortedClassValues, rows);
+
+        if ((Maximization.Value && quality > bestQuality) ||
+            (!Maximization.Value && quality < bestQuality)) {
+          bestQuality = quality;
+          bestTree = tree;
+        }
+      }
+
+      // if the best validation tree is better than the current best solution => update
+      bool newBest =
+        BestValidationQuality == null ||
+        (Maximization.Value && bestQuality > BestValidationQuality.Value) ||
+        (!Maximization.Value && bestQuality < BestValidationQuality.Value);
+      if (newBest) {
+        var model = new SymbolicRegressionModel((ISymbolicExpressionTreeInterpreter)SymbolicExpressionTreeInterpreter.Clone(),
+          bestTree);
+
+        if (BestValidationSolution == null) {
+          BestValidationSolution = new SymbolicClassificationSolution(ClassificationProblemData, model, LowerEstimationLimit.Value, UpperEstimationLimit.Value);
+          BestValidationSolution.Name = BestValidationSolutionParameterName;
+          BestValidationSolution.Description = "Best solution on validation partition found over the whole run.";
+          BestValidationQuality = new DoubleValue(bestQuality);
+          Results.Add(new Result(BestValidationSolutionParameterName, BestValidationSolution));
+          Results.Add(new Result(BestValidationQualityParameterName, BestValidationQuality));
+
+        } else {
+          BestValidationSolution.Model = model;
+          BestValidationQuality.Value = bestQuality;
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SingleObjectiveSymbolicClassificationEvaluator.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SingleObjectiveSymbolicClassificationEvaluator.cs	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SingleObjectiveSymbolicClassificationEvaluator.cs	(revision 4366)
@@ -61,6 +61,6 @@
     }
 
-    public ILookupParameter<DataAnalysisProblemData> RegressionProblemDataParameter {
-      get { return (ILookupParameter<DataAnalysisProblemData>)Parameters[RegressionProblemDataParameterName]; }
+    public ILookupParameter<ClassificationProblemData> RegressionProblemDataParameter {
+      get { return (ILookupParameter<ClassificationProblemData>)Parameters[RegressionProblemDataParameterName]; }
     }
 
@@ -92,5 +92,5 @@
       get { return SymbolicExpressionTreeParameter.ActualValue; }
     }
-    public DataAnalysisProblemData RegressionProblemData {
+    public ClassificationProblemData RegressionProblemData {
       get { return RegressionProblemDataParameter.ActualValue; }
     }
@@ -118,5 +118,5 @@
       Parameters.Add(new LookupParameter<ISymbolicExpressionTreeInterpreter>(SymbolicExpressionTreeInterpreterParameterName, "The interpreter that should be used to calculate the output values of the symbolic expression tree."));
       Parameters.Add(new LookupParameter<SymbolicExpressionTree>(FunctionTreeParameterName, "The symbolic regression solution encoded as a symbolic expression tree."));
-      Parameters.Add(new LookupParameter<DataAnalysisProblemData>(RegressionProblemDataParameterName, "The problem data on which the symbolic regression solution should be evaluated."));
+      Parameters.Add(new LookupParameter<ClassificationProblemData>(RegressionProblemDataParameterName, "The problem data on which the symbolic regression solution should be evaluated."));
       Parameters.Add(new ValueLookupParameter<IntValue>(SamplesStartParameterName, "The start index of the dataset partition on which the symbolic regression solution should be evaluated."));
       Parameters.Add(new ValueLookupParameter<IntValue>(SamplesEndParameterName, "The end index of the dataset partition on which the symbolic regression solution should be evaluated."));
@@ -139,7 +139,7 @@
       int seed = Random.Next();
       IEnumerable<int> rows = GenerateRowsToEvaluate(seed, RelativeNumberOfEvaluatedSamples.Value, SamplesStart.Value, SamplesEnd.Value);
+
       double quality = Evaluate(SymbolicExpressionTreeInterpreter, SymbolicExpressionTree, LowerEstimationLimit.Value, UpperEstimationLimit.Value,
-        RegressionProblemData.Dataset,
-        RegressionProblemData.TargetVariable.Value, rows);
+        RegressionProblemData.Dataset, RegressionProblemData.TargetVariable.Value, RegressionProblemData.SortedClassValues, rows);
       QualityParameter.ActualValue = new DoubleValue(quality);
       return base.Apply();
@@ -157,4 +157,5 @@
       Dataset dataset,
       string targetVariable,
+      IEnumerable<double> sortedClassValues,
       IEnumerable<int> rows);
   }
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationMeanSquaredErrorEvaluator.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationMeanSquaredErrorEvaluator.cs	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationMeanSquaredErrorEvaluator.cs	(revision 4366)
@@ -22,4 +22,6 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
@@ -37,10 +39,10 @@
     }
 
-    public override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<int> rows) {
-      double mse = Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, dataset, targetVariable, rows);
+    public override double Evaluate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<double> sortedClassValues, IEnumerable<int> rows) {
+      double mse = Calculate(interpreter, solution, lowerEstimationLimit, upperEstimationLimit, dataset, targetVariable, sortedClassValues, rows);
       return mse;
     }
 
-    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<int> rows) {
+    public static double Calculate(ISymbolicExpressionTreeInterpreter interpreter, SymbolicExpressionTree solution, double lowerEstimationLimit, double upperEstimationLimit, Dataset dataset, string targetVariable, IEnumerable<double> sortedClassValues, IEnumerable<int> rows) {
       IEnumerable<double> estimatedValues = interpreter.GetSymbolicExpressionTreeValues(solution, dataset, rows);
       IEnumerable<double> originalValues = dataset.GetEnumeratedVariableValues(targetVariable, rows);
@@ -49,4 +51,7 @@
       OnlineMeanSquaredErrorEvaluator mseEvaluator = new OnlineMeanSquaredErrorEvaluator();
 
+
+      double firstClassValue = sortedClassValues.First();
+      double lastClassValue = sortedClassValues.Last();
       while (originalEnumerator.MoveNext() && estimatedEnumerator.MoveNext()) {
         double estimated = estimatedEnumerator.Current;
@@ -54,4 +59,8 @@
         if (double.IsNaN(estimated))
           estimated = upperEstimationLimit;
+        else if (estimated < original && original.IsAlmost(firstClassValue))
+          estimated = original;
+        else if (estimated > original && original.IsAlmost(lastClassValue))
+          estimated = original;
         else
           estimated = Math.Min(upperEstimationLimit, Math.Max(lowerEstimationLimit, estimated));
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationProblem.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationProblem.cs	(revision 4325)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationProblem.cs	(revision 4366)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Core;
@@ -28,8 +29,10 @@
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Creators;
 using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Interfaces;
+using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding.Symbols;
 using HeuristicLab.Parameters;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.PluginInfrastructure;
 using HeuristicLab.Problems.DataAnalysis.Symbolic;
+using HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols;
 
 namespace HeuristicLab.Problems.DataAnalysis.Classification {
@@ -52,6 +55,6 @@
       protected set { SymbolicExpressionTreeInterpreterParameter.Value = value; }
     }
-    public ValueParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
-      get { return (ValueParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
+    public IValueParameter<ISymbolicExpressionTreeInterpreter> SymbolicExpressionTreeInterpreterParameter {
+      get { return (IValueParameter<ISymbolicExpressionTreeInterpreter>)Parameters[SymbolicExpressionTreeInterpreterParameterName]; }
     }
 
@@ -60,6 +63,6 @@
       protected set { FunctionTreeGrammarParameter.Value = value; }
     }
-    public ValueParameter<ISymbolicExpressionGrammar> FunctionTreeGrammarParameter {
-      get { return (ValueParameter<ISymbolicExpressionGrammar>)Parameters[FunctionTreeGrammarParameterName]; }
+    public IValueParameter<ISymbolicExpressionGrammar> FunctionTreeGrammarParameter {
+      get { return (IValueParameter<ISymbolicExpressionGrammar>)Parameters[FunctionTreeGrammarParameterName]; }
     }
 
@@ -68,6 +71,6 @@
       protected set { MaxExpressionLengthParameter.Value = value; }
     }
-    public ValueParameter<IntValue> MaxExpressionLengthParameter {
-      get { return (ValueParameter<IntValue>)Parameters[MaxExpressionLengthParameterName]; }
+    public IValueParameter<IntValue> MaxExpressionLengthParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxExpressionLengthParameterName]; }
     }
 
@@ -84,6 +87,6 @@
       protected set { UpperEstimationLimitParameter.Value = value; }
     }
-    public ValueParameter<DoubleValue> UpperEstimationLimitParameter {
-      get { return (ValueParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
+    public IValueParameter<DoubleValue> UpperEstimationLimitParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[UpperEstimationLimitParameterName]; }
     }
 
@@ -92,6 +95,6 @@
       protected set { LowerEstimationLimitParameter.Value = value; }
     }
-    public ValueParameter<DoubleValue> LowerEstimationLimitParameter {
-      get { return (ValueParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
+    public IValueParameter<DoubleValue> LowerEstimationLimitParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[LowerEstimationLimitParameterName]; }
     }
 
@@ -100,6 +103,6 @@
       protected set { MaxFunctionDefiningBranchesParameter.Value = value; }
     }
-    public ValueParameter<IntValue> MaxFunctionDefiningBranchesParameter {
-      get { return (ValueParameter<IntValue>)Parameters[MaxFunctionDefiningBranchensParameterName]; }
+    public IValueParameter<IntValue> MaxFunctionDefiningBranchesParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxFunctionDefiningBranchensParameterName]; }
     }
 
@@ -108,6 +111,6 @@
       protected set { MaxFunctionArgumentsParameter.Value = value; }
     }
-    public ValueParameter<IntValue> MaxFunctionArgumentsParameter {
-      get { return (ValueParameter<IntValue>)Parameters[MaxFunctionArgumentsParameterName]; }
+    public IValueParameter<IntValue> MaxFunctionArgumentsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxFunctionArgumentsParameterName]; }
     }
 
@@ -225,4 +228,5 @@
       Operators.AddRange(ApplicationManager.Manager.GetInstances<ISymbolicExpressionTreeOperator>().OfType<IOperator>());
       Operators.Add(new MinAverageMaxSymbolicExpressionTreeSizeAnalyzer());
+      Operators.Add(new ValidationBestSymbolicClassificationSolutionAnalyzer());
     }
 
@@ -249,4 +253,7 @@
 
     private void ParameterizeGrammar() {
+      List<LaggedVariable> laggedSymbols = FunctionTreeGrammar.Symbols.OfType<LaggedVariable>().ToList();
+      foreach (Symbol symbol in laggedSymbols)
+        FunctionTreeGrammar.RemoveSymbol(symbol);
       foreach (var varSymbol in FunctionTreeGrammar.Symbols.OfType<HeuristicLab.Problems.DataAnalysis.Symbolic.Symbols.Variable>()) {
         varSymbol.VariableNames = ClassificationProblemData.InputVariables.CheckedItems.Select(x => x.Value.Value);
@@ -287,5 +294,17 @@
 
     private void ParameterizeAnalyzers() {
-
+      foreach (ISymbolicExpressionTreeAnalyzer analyzer in Operators.OfType<ISymbolicExpressionTreeAnalyzer>()) {
+        analyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+        var bestValidationSolutionAnalyzer = analyzer as ValidationBestSymbolicClassificationSolutionAnalyzer;
+        if (bestValidationSolutionAnalyzer != null) {
+          bestValidationSolutionAnalyzer.ClassificationProblemDataParameter.ActualName = ClassificationProblemDataParameter.Name;
+          bestValidationSolutionAnalyzer.UpperEstimationLimitParameter.ActualName = UpperEstimationLimitParameter.Name;
+          bestValidationSolutionAnalyzer.LowerEstimationLimitParameter.ActualName = LowerEstimationLimitParameter.Name;
+          bestValidationSolutionAnalyzer.SymbolicExpressionTreeInterpreterParameter.ActualName = SymbolicExpressionTreeInterpreterParameter.Name;
+          bestValidationSolutionAnalyzer.SymbolicExpressionTreeParameter.ActualName = SolutionCreator.SymbolicExpressionTreeParameter.ActualName;
+          bestValidationSolutionAnalyzer.ValidationSamplesStartParameter.Value = ValidationSamplesStart;
+          bestValidationSolutionAnalyzer.ValidationSamplesEndParameter.Value = ValidationSamplesEnd;
+        }
+      }
     }
     #endregion
Index: branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationSolution.cs
===================================================================
--- branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationSolution.cs	(revision 4366)
+++ branches/HeuristicLab.Classification/HeuristicLab.Problems.DataAnalysis.Classification/3.3/Symbolic/SymbolicClassificationSolution.cs	(revision 4366)
@@ -0,0 +1,214 @@
+﻿#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.Drawing;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis.Regression.Symbolic;
+
+namespace HeuristicLab.Problems.DataAnalysis.Classification {
+  /// <summary>
+  /// Represents a solution for a symbolic regression problem which can be visualized in the GUI.
+  /// </summary>
+  [Item("SymbolicClassificationSolution", "Represents a solution for a symbolic classification problem which can be visualized in the GUI.")]
+  [StorableClass]
+  public sealed class SymbolicClassificationSolution : DataAnalysisSolution, IClassificationSolution {
+    private SymbolicClassificationSolution() : base() { }
+    public SymbolicClassificationSolution(ClassificationProblemData problemData, SymbolicRegressionModel model, double lowerEstimationLimit, double upperEstimationLimit)
+      : base(problemData, lowerEstimationLimit, upperEstimationLimit) {
+      this.Model = model;
+    }
+
+    public override Image ItemImage {
+      get { return HeuristicLab.Common.Resources.VS2008ImageLibrary.Function; }
+    }
+
+    public new ClassificationProblemData ProblemData {
+      get { return (ClassificationProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public new SymbolicRegressionModel Model {
+      get { return (SymbolicRegressionModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    protected override void RecalculateEstimatedValues() {
+      estimatedValues =
+          (from x in Model.GetEstimatedValues(ProblemData, 0, ProblemData.Dataset.Rows)
+           let boundedX = Math.Min(UpperEstimationLimit, Math.Max(LowerEstimationLimit, x))
+           select double.IsNaN(boundedX) ? UpperEstimationLimit : boundedX).ToList();
+      RecalculateClassIntermediates();
+      OnEstimatedValuesChanged();
+    }
+
+    private void RecalculateClassIntermediates() {
+      int slices = 1000;
+
+      List<KeyValuePair<double, double>> estimatedTargetValues =
+        (from row in Enumerable.Range(ProblemData.TrainingSamplesStart.Value, ProblemData.TrainingSamplesEnd.Value - ProblemData.TrainingSamplesStart.Value)
+         select new KeyValuePair<double, double>(
+           estimatedValues[row],
+           ProblemData.Dataset[ProblemData.TargetVariable.Value, row])).ToList();
+
+      List<double> originalClasses = ProblemData.Dataset.GetVariableValues(ProblemData.TargetVariable.Value).Distinct().OrderBy(x => x).ToList();
+      int numberOfClasses = originalClasses.Count;
+
+      double[] thresholds = new double[numberOfClasses + 1];
+      thresholds[0] = double.NegativeInfinity;
+      thresholds[thresholds.Length - 1] = double.PositiveInfinity;
+
+
+      for (int i = 1; i < thresholds.Length - 1; i++) {
+        double lowerThreshold = thresholds[i - 1];
+        double actualThreshold = originalClasses[i - 1];
+        double thresholdIncrement = (originalClasses[i] - originalClasses[i - 1]) / slices;
+
+        double bestThreshold = double.NaN;
+        double bestQuality = double.NegativeInfinity;
+
+        while (actualThreshold < originalClasses[i]) {
+          int truePosivites = 0;
+          int falsePosivites = 0;
+          int trueNegatives = 0;
+          int falseNegatives = 0;
+
+          foreach (KeyValuePair<double, double> estimatedTarget in estimatedTargetValues) {
+            //all positives
+            if (estimatedTarget.Value.IsAlmost(originalClasses[i - 1])) {
+              if (estimatedTarget.Key > lowerThreshold && estimatedTarget.Key < actualThreshold)
+                truePosivites++;
+              else
+                falseNegatives++;
+            }
+              //all negatives
+            else {
+              if (estimatedTarget.Key > lowerThreshold && estimatedTarget.Key < actualThreshold)
+                falsePosivites++;
+              else
+                trueNegatives++;
+            }
+          }
+
+          //mkommend 30.08.2010
+          //matthews correlation coefficient taken from http://en.wikipedia.org/wiki/Matthews_correlation_coefficient
+          //MCC = [(TP * FP) - (FP * FN)] / sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN))
+          double dividend = truePosivites * falsePosivites - falsePosivites * falseNegatives;
+          double divisor = Math.Sqrt((truePosivites + falsePosivites) * (truePosivites + falsePosivites) *
+            (trueNegatives + falsePosivites) * (trueNegatives + falseNegatives));
+          if (divisor == 0)
+            divisor = 1;
+
+          double mcc = dividend / divisor;
+
+          if (bestQuality < mcc) {
+            bestQuality = mcc;
+            bestThreshold = actualThreshold;
+          }
+          actualThreshold += thresholdIncrement;
+        }
+        thresholds[i] = bestThreshold;
+      }
+      this.optimalThresholds = new List<double>(thresholds);
+      this.actualThresholds = optimalThresholds;
+    }
+
+    #region properties
+    private List<double> optimalThresholds;
+    private List<double> actualThresholds;
+    public IEnumerable<double> Thresholds {
+      get {
+        if (actualThresholds == null) RecalculateEstimatedValues();
+        return actualThresholds;
+      }
+      set {
+        if (actualThresholds != null && actualThresholds.SequenceEqual(value))
+          return;
+        actualThresholds = new List<double>(value);
+        OnThresholdsChanged();
+      }
+    }
+
+    private List<double> estimatedValues;
+    public override IEnumerable<double> EstimatedValues {
+      get {
+        if (estimatedValues == null) RecalculateEstimatedValues();
+        return estimatedValues.AsEnumerable();
+      }
+    }
+
+    public IEnumerable<double> EstimatedClassValues {
+      get {
+        double[] classValues = ProblemData.SortedClassValues.ToArray();
+        foreach (double value in EstimatedValues) {
+          int classIndex = 0;
+          while (value > actualThresholds[classIndex + 1])
+            classIndex++;
+          yield return classValues[classIndex];
+        }
+      }
+    }
+
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get {
+        if (estimatedValues == null) RecalculateEstimatedValues();
+        int start = ProblemData.TrainingSamplesStart.Value;
+        int n = ProblemData.TrainingSamplesEnd.Value - start;
+        return estimatedValues.Skip(start).Take(n).ToList();
+      }
+    }
+    public IEnumerable<double> EstimatedTrainingClassValues {
+      get {
+        int start = ProblemData.TrainingSamplesStart.Value;
+        int n = ProblemData.TrainingSamplesEnd.Value - start;
+        return EstimatedClassValues.Skip(start).Take(n).ToList();
+      }
+    }
+
+    public override IEnumerable<double> EstimatedTestValues {
+      get {
+        if (estimatedValues == null) RecalculateEstimatedValues();
+        int start = ProblemData.TestSamplesStart.Value;
+        int n = ProblemData.TestSamplesEnd.Value - start;
+        return estimatedValues.Skip(start).Take(n).ToList();
+      }
+    }
+    public IEnumerable<double> EstimatedTestClassValues {
+      get {
+        int start = ProblemData.TestSamplesStart.Value;
+        int n = ProblemData.TestSamplesEnd.Value - start;
+        return EstimatedClassValues.Skip(start).Take(n).ToList();
+      }
+    }
+    #endregion
+
+    public event EventHandler ThresholdsChanged;
+    private void OnThresholdsChanged() {
+      var handler = ThresholdsChanged;
+      if (handler != null)
+        ThresholdsChanged(this, EventArgs.Empty);
+    }
+  }
+}
