Index: /branches/1776_ClassificationEnsembleVoting/Build.cmd
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/Build.cmd	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/Build.cmd	(revision 16097)
@@ -0,0 +1,94 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=0
+
+SET SELECTED=
+SET CONFIGURATION=
+SET PLATFORM=
+
+IF "%~1"=="" GOTO :prompt_solution
+
+SET SELECTED=%1
+IF NOT EXIST %SELECTED% (
+  ECHO Solution file %SELECTED% could not be found.
+  GOTO :end
+)
+ECHO Building solution %SELECTED% ...
+GOTO :config_selection
+
+:prompt_solution
+SET /A COUNT=0
+FOR /F "tokens=*" %%A IN ('dir /B *.sln') DO (
+  CALL :forloopbody "%%A"
+)
+
+IF "%COUNT%"=="1" (
+  SET SELECTED=%SOLUTIONS.1%
+  ECHO Building %SOLUTIONS.1% as it is the only solution that was found ...
+  GOTO :config_selection
+)
+
+ECHO Found the following solutions:
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO ECHO %%A = %%B
+ECHO.
+SET /P SOLUTIONINDEX=Which solution to build? Type the number: 
+
+SET SELECTED=""
+FOR /F "tokens=2* delims=.=" %%A IN ('SET SOLUTIONS.') DO (
+  IF "%%A"=="%SOLUTIONINDEX%" SET SELECTED=%%B
+)
+
+IF %SELECTED%=="" GOTO :eof
+
+:config_selection
+IF "%~2"==""  GOTO :prompt_config
+
+SET CONFIGURATION=%~2
+ECHO Building configuration %CONFIGURATION% ...
+GOTO :platform_selection
+
+:prompt_config
+SET /P CONFIGURATION=Which configuration to build [Release]: 
+IF "%CONFIGURATION%"=="" SET CONFIGURATION=Release
+
+:platform_selection
+IF "%~3"=="" GOTO :prompt_platform
+  
+SET PLATFORM=%~3
+ECHO Building platform %PLATFORM% ...
+GOTO :main
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:main
+REM First find the path to the msbuild.exe by performing a registry query
+FOR /F "tokens=1,3 delims=	 " %%A IN ('REG QUERY "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSBuild\ToolsVersions\4.0"') DO (
+  IF "%%A"=="MSBuildToolsPath" SET MSBUILDPATH=%%B)
+
+REM Then execute msbuild to clean and build the solution
+REM Disable that msbuild creates a cache file of the solution
+SET MSBuildUseNoSolutionCache=1
+REM Run msbuild to clean and then build
+IF "%CLEANBEFOREBUILD%"=="1" (
+  ECHO Cleaning ...
+  %MSBUILDPATH%msbuild.exe %SELECTED% /target:Clean /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+)
+ECHO Building ...
+%MSBUILDPATH%msbuild.exe %SELECTED% /target:Rebuild /p:Configuration="%CONFIGURATION%",Platform="%PLATFORM%" /m:2 /nologo /verbosity:q /clp:ErrorsOnly
+
+ECHO.
+ECHO DONE.
+
+:end
+
+PAUSE
+
+GOTO :eof
+
+REM This workaround is necessary so that COUNT gets reevaluated
+:forloopbody
+SET /A COUNT+=1
+SET SOLUTIONS.%COUNT%=%1
+GOTO :eof
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.sln
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.sln	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.sln	(revision 16097)
@@ -0,0 +1,59 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}"
+	ProjectSection(SolutionItems) = preProject
+		Build.cmd = Build.cmd
+		ConfigMerger.exe = ConfigMerger.exe
+		..\documentation\License\gpl-3.0.txt = ..\documentation\License\gpl-3.0.txt
+		HeuristicLab 3.3.vsmdi = HeuristicLab 3.3.vsmdi
+		MergeConfigs.cmd = MergeConfigs.cmd
+		PreBuildEvent.cmd = PreBuildEvent.cmd
+	EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis-3.4", "HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj", "{DF87C13E-A889-46FF-8153-66DCAA8C5674}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.DataAnalysis.Views-3.4", "HeuristicLab.Problems.DataAnalysis.Views\3.4\HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj", "{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}"
+EndProject
+Global
+	GlobalSection(TestCaseManagementSettings) = postSolution
+		CategoryFile = HeuristicLab 3.3.vsmdi
+	EndGlobalSection
+	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
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|x64.ActiveCfg = Debug|x64
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|x64.Build.0 = Debug|x64
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|x86.ActiveCfg = Debug|x86
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Debug|x86.Build.0 = Debug|x86
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|x64.ActiveCfg = Release|x64
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|x64.Build.0 = Release|x64
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|x86.ActiveCfg = Release|x86
+		{DF87C13E-A889-46FF-8153-66DCAA8C5674}.Release|x86.Build.0 = Release|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x64.ActiveCfg = Debug|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x64.Build.0 = Debug|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x86.ActiveCfg = Debug|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Debug|x86.Build.0 = Debug|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|Any CPU.Build.0 = Release|Any CPU
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x64.ActiveCfg = Release|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x64.Build.0 = Release|x64
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x86.ActiveCfg = Release|x86
+		{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.vsmdi
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.vsmdi	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab 3.3.vsmdi	(revision 16097)
@@ -0,0 +1,48 @@
+﻿<?xml version="1.0" encoding="UTF-8"?>
+<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
+  <TestList name="Create Samples Tests" id="12acbb59-0ff6-4a9a-8f98-201e7d9412f9" parentListId="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+    <TestLinks>
+      <TestLink id="fc406b79-142c-bb12-8287-0bc768acd728" name="CreateIslandGaTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="77c479e4-8f9a-5474-b026-e5c0811c8eb0" name="CreateLocalSearchKnapsackSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="45db65d6-d6b2-67e4-1bec-293528739529" name="CreateEsGriewankSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="74b708a9-14d0-3cc3-d72e-139d1a27f5ef" name="CreateGaTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="5c5fb63e-d219-6818-bba2-9f66dbe4d727" name="CreateGpSymbolicRegressionSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="6c054fba-432a-4fe2-507f-e2083c998056" name="CreatePsoSchwefelSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="0b6b45a4-99ea-b020-805a-1652f0f5b5a7" name="CreateSimulatedAnnealingRastriginSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="51e968a7-120f-dd28-9514-ad35d3ee66d2" name="CreateGaVrpSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="0d883f66-2fc5-99fc-eabb-2dff566104f5" name="CreateTabuSearchTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="c8ea68e8-b9d7-24cb-5540-655f58da13bf" name="CreateGpArtificialAntSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="e6f3ab8a-1630-560c-c8b9-4e8ce2522172" name="CreateVnsTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="29257c28-7dfb-f227-00a4-776d74b02a7b" name="CreateGpSymbolicClassificationSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+    </TestLinks>
+  </TestList>
+  <TestList name="Basic Tests" id="3f8b3bd5-248c-46a8-84cf-7d035eb3c815" parentListId="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+    <TestLinks>
+      <TestLink id="36916402-ba0c-751d-366b-380dac87dcef" name="CheckPluginDependenciesForReferencedAssemblies" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="29ead60b-2ae7-821a-ccc3-e5e4769661b7" name="TestStorableConstructor" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="2028e687-d144-bb6f-bb05-ac86eaec07ee" name="TestCloningAllDeepCloneables" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="3983eb26-fd15-5b88-1fd7-07b363511b10" name="TestCloningConstructor" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="34ed65f1-46f7-d2e6-64cc-c2d958294d8b" name="CheckReferenceAssembliesForPluginDependencies" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="ec4d1ddf-ed6b-9f9e-29a0-d9e558856af1" name="ContentViewAttributeTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+    </TestLinks>
+  </TestList>
+  <TestList name="Run Samples Tests" id="40b94fb3-06ad-41f8-bb3f-dc90c2510684" parentListId="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+    <TestLinks>
+      <TestLink id="8bb23f49-5206-4245-08b9-471f543b3e21" name="RunGpSymbolicRegressionSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="1f743a89-461d-5650-31ba-e68c02f0fbad" name="RunGaVrpSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="f8489a03-acca-11d3-53cb-8e24d5f2bc12" name="RunIslandGaTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="0f7f90f7-e380-ff65-538e-ae559774092a" name="RunPsoSchwefelSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="53547167-fc2b-4954-b200-2cc27b4c4951" name="RunVnsTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="7512aa68-9dbe-f891-d1da-99dc94661142" name="RunEsGriewankSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="433a86f1-0126-5281-1c23-90b47f066d94" name="RunGpSymbolicClassificationSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="eec82cf0-dae7-63c8-a469-6dd84d49a935" name="RunGaTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="7d7f6024-f783-1c71-db60-2d6746653109" name="RunSimulatedAnnealingRastriginSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="29188193-8d50-0c61-c6fa-4d5b608a72e8" name="RunGpArtificialAntSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="95278ae9-832c-bef9-0bbc-4432195e63fa" name="RunTabuSearchTspSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+      <TestLink id="21f1371d-8c47-9588-d8fa-cf45fd1d81eb" name="RunLocalSearchKnapsackSampleTest" storage="heuristiclab.tests\bin\release\heuristiclab.tests.dll" type="Microsoft.VisualStudio.TestTools.TestTypes.Unit.UnitTestElement, Microsoft.VisualStudio.QualityTools.Tips.UnitTest.ObjectModel, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+    </TestLinks>
+  </TestList>
+  <TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
+    <RunConfiguration id="f9392825-866f-4434-be36-358db28f0c59" name="Local Test Run" storage="localtestrun.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  </TestList>
+</TestLists>
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.Designer.cs	(revision 16097)
@@ -0,0 +1,116 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationEnsembleSolutionAccuracyToCoveredSamples {
+    /// <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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.SamplesComboBox = new System.Windows.Forms.ComboBox();
+      this.AUCLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea";
+      this.chart.ChartAreas.Add(chartArea1);
+      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, 30);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(358, 195);
+      this.chart.TabIndex = 0;
+      // 
+      // SamplesComboBox
+      // 
+      this.SamplesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.SamplesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.SamplesComboBox.FormattingEnabled = true;
+      this.SamplesComboBox.Location = new System.Drawing.Point(3, 3);
+      this.SamplesComboBox.Name = "SamplesComboBox";
+      this.SamplesComboBox.Size = new System.Drawing.Size(355, 21);
+      this.SamplesComboBox.TabIndex = 1;
+      this.SamplesComboBox.SelectedIndexChanged += new System.EventHandler(this.SamplesComboBox_SelectedIndexChanged);
+      // 
+      // AUCLabel
+      // 
+      this.AUCLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.AUCLabel.BackColor = System.Drawing.Color.Transparent;
+      this.AUCLabel.Location = new System.Drawing.Point(162, 97);
+      this.AUCLabel.Name = "AUCLabel";
+      this.AUCLabel.Size = new System.Drawing.Size(29, 13);
+      this.AUCLabel.TabIndex = 2;
+      this.AUCLabel.Text = "AUC";
+      this.AUCLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+      // 
+      // ClassificationEnsembleSolutionAccuracyToCoveredSamples
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.AUCLabel);
+      this.Controls.Add(this.SamplesComboBox);
+      this.Controls.Add(this.chart);
+      this.Name = "ClassificationEnsembleSolutionAccuracyToCoveredSamples";
+      this.Size = new System.Drawing.Size(358, 225);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.ComboBox SamplesComboBox;
+    protected System.Windows.Forms.Label AUCLabel;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionAccuracyToCoveredSamples.cs	(revision 16097)
@@ -0,0 +1,232 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Accuracy Covered Dependence")]
+  [Content(typeof(IClassificationEnsembleSolution))]
+  public partial class ClassificationEnsembleSolutionAccuracyToCoveredSamples : DataAnalysisSolutionEvaluationView {
+    private const string ACCURACYCOVERED = "Accuracy to Covered percentage";
+    private const string AREA = "Area";
+
+    private const string SamplesComboBoxAllSamples = "All Samples";
+    private const string SamplesComboBoxTrainingSamples = "Training Samples";
+    private const string SamplesComboBoxTestSamples = "Test Samples";
+
+    private const int maxPoints = 101;
+
+    public new ClassificationEnsembleSolution Content {
+      get { return (ClassificationEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationEnsembleSolutionAccuracyToCoveredSamples()
+      : base() {
+      InitializeComponent();
+
+      SamplesComboBox.Items.AddRange(new string[] { SamplesComboBoxAllSamples, SamplesComboBoxTrainingSamples, SamplesComboBoxTestSamples });
+      SamplesComboBox.SelectedIndex = 0;
+      //configure axis
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].AxisX.Minimum = 0;
+      this.chart.ChartAreas[0].AxisX.Maximum = 1;
+      this.chart.ChartAreas[0].AxisX.Title = "Covered Samples in %";
+
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].AxisY.Minimum = 0;
+      this.chart.ChartAreas[0].AxisY.Maximum = 1;
+      this.chart.ChartAreas[0].AxisY.Title = "Accuracy";
+
+      AUCLabel.Parent = chart;
+      AUCLabel.BackColor = Color.Transparent;
+    }
+
+    private void RedrawChart() {
+      this.chart.Series.Clear();
+      if (Content != null) {
+
+        double[] accuracy = new double[maxPoints + 1];
+        double[] covered = new double[maxPoints + 1];
+
+        IClassificationEnsembleSolutionWeightCalculator weightCalc = Content.WeightCalculator;
+        var solutions = Content.ClassificationSolutions;
+        double[] estimatedClassValues = null;
+        double[] target;
+        OnlineAccuracyCalculator accuracyCalc = new OnlineAccuracyCalculator();
+
+        int[] indizes;
+        double[] confidences;
+
+        target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
+        switch (SamplesComboBox.SelectedItem.ToString()) {
+          case SamplesComboBoxAllSamples:
+            indizes = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray();
+            estimatedClassValues = Content.EstimatedClassValues.ToArray();
+            confidences = weightCalc.GetConfidence(solutions,
+                                                   Enumerable.Range(0, Content.ProblemData.Dataset.Rows),
+                                                   estimatedClassValues,
+                                                   weightCalc.GetAllClassDelegate()).ToArray();
+            break;
+          case SamplesComboBoxTrainingSamples:
+            indizes = Content.ProblemData.TrainingIndices.ToArray();
+            estimatedClassValues = Content.EstimatedTrainingClassValues.ToArray();
+            confidences = weightCalc.GetConfidence(solutions,
+                                                   Content.ProblemData.TrainingIndices,
+                                                   estimatedClassValues,
+                                                   weightCalc.GetTrainingClassDelegate()).ToArray();
+            break;
+          case SamplesComboBoxTestSamples:
+            indizes = Content.ProblemData.TestIndices.ToArray();
+            estimatedClassValues = Content.EstimatedTestClassValues.ToArray();
+            confidences = weightCalc.GetConfidence(solutions,
+                                                   Content.ProblemData.TestIndices,
+                                                   estimatedClassValues,
+                                                   weightCalc.GetTestClassDelegate()).ToArray();
+            break;
+          default:
+            throw new ArgumentException();
+        }
+
+        if (!estimatedClassValues.All(x => Double.IsNaN(x))) {
+          int row;
+          for (int i = 0; i < maxPoints; i++) {
+            double confidenceValue = (1.0 / (maxPoints - 1)) * i;
+            int notCovered = 0;
+
+            for (int j = 0; j < indizes.Length; j++) {
+              row = indizes[j];
+              if (confidences[j] >= confidenceValue) {
+                accuracyCalc.Add(target[row], estimatedClassValues[j]);
+              } else {
+                notCovered++;
+              }
+            }
+
+            accuracy[i + 1] = accuracyCalc.Accuracy;
+            if (indizes.Length > 0) {
+              covered[i] = 1.0 - (double)notCovered / (double)indizes.Length;
+            }
+            accuracyCalc.Reset();
+          }
+
+          accuracy[0] = accuracy[1];
+          covered[maxPoints] = 0.0;
+
+          accuracy = accuracy.Reverse().ToArray();
+          covered = covered.Reverse().ToArray();
+
+          Series area = this.chart.Series.Add(AREA);
+          area.ChartType = SeriesChartType.Area;
+          area.Color = Color.LightBlue;
+          IEnumerable<IEnumerable<double>> areaPoints = CalculateAreaPoints(covered, accuracy);
+          area.Points.DataBindXY(areaPoints.ElementAt(0), areaPoints.ElementAt(1));
+
+          Series series = this.chart.Series.Add(ACCURACYCOVERED);
+          series.Color = Color.Red;
+          series.ChartType = SeriesChartType.FastPoint;
+          series.MarkerStyle = MarkerStyle.Diamond;
+          series.MarkerSize = 5;
+          series.Points.DataBindXY(covered, accuracy);
+
+          double auc = CalculateAreaUnderCurve(series);
+          area.LegendToolTip = "AUC: " + auc;
+
+          AUCLabel.Text = "AUC: " + auc;
+        } else {
+          AUCLabel.Text = "No values in this partition!";
+        }
+      }
+    }
+
+    private IEnumerable<IEnumerable<double>> CalculateAreaPoints(double[] covered, double[] accuracy) {
+      List<double> newCovered = new List<double>();
+      List<double> worseAccuracy = new List<double>();
+      newCovered.Add(covered[0]);
+      worseAccuracy.Add(accuracy[0]);
+      for (int i = 1; i < covered.Length; i++) {
+        if (accuracy[i] > accuracy[i - 1]) {
+          worseAccuracy.Add(accuracy[i - 1]);
+          newCovered.Add(covered[i] - Double.Epsilon);
+        } else {
+          worseAccuracy.Add(accuracy[i]);
+          newCovered.Add(covered[i - 1] + Double.Epsilon);
+        }
+        worseAccuracy.Add(accuracy[i]);
+        newCovered.Add(covered[i]);
+      }
+      return new List<IEnumerable<double>>() { newCovered, worseAccuracy };
+    }
+
+    private double CalculateAreaUnderCurve(Series series) {
+      if (series.Points.Count < 1) throw new ArgumentException("Could not calculate area under curve if less than 1 data points were given.");
+
+      double auc = 0.0;
+      for (int i = 1; i < series.Points.Count; i++) {
+        double width = series.Points[i].XValue - series.Points[i - 1].XValue;
+        double y1 = series.Points[i - 1].YValues[0];
+        double y2 = series.Points[i].YValues[0];
+
+        auc += (y1 + y2) * width / 2;
+      }
+
+      return auc;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void SamplesComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
@@ -0,0 +1,144 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationEnsembleSolutionEstimatedClassValuesView {
+    /// <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() {
+      this.SamplesComboBox = new System.Windows.Forms.ComboBox();
+      this.CorrectClassifiedConfidenceLabel = new System.Windows.Forms.Label();
+      this.WrongClassifiedConfidenceLabel = new System.Windows.Forms.Label();
+      this.CorrectClassifiedConfidence = new System.Windows.Forms.TextBox();
+      this.WrongClassifiedConfidence = new System.Windows.Forms.TextBox();
+      this.SuspendLayout();
+      // 
+      // matrixView
+      // 
+      this.matrixView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.matrixView.Dock = System.Windows.Forms.DockStyle.None;
+      this.matrixView.Location = new System.Drawing.Point(3, 31);
+      this.matrixView.Size = new System.Drawing.Size(653, 251);
+      // 
+      // SamplesComboBox
+      // 
+      this.SamplesComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.SamplesComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.SamplesComboBox.FormattingEnabled = true;
+      this.SamplesComboBox.Location = new System.Drawing.Point(4, 4);
+      this.SamplesComboBox.Name = "SamplesComboBox";
+      this.SamplesComboBox.Size = new System.Drawing.Size(230, 21);
+      this.SamplesComboBox.TabIndex = 2;
+      this.SamplesComboBox.SelectedIndexChanged += new System.EventHandler(this.SamplesComboBox_SelectedIndexChanged);
+      // 
+      // CorrectClassifiedConfidenceLabel
+      // 
+      this.CorrectClassifiedConfidenceLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.CorrectClassifiedConfidenceLabel.AutoSize = true;
+      this.CorrectClassifiedConfidenceLabel.Location = new System.Drawing.Point(240, 7);
+      this.CorrectClassifiedConfidenceLabel.Name = "CorrectClassifiedConfidenceLabel";
+      this.CorrectClassifiedConfidenceLabel.Size = new System.Drawing.Size(103, 13);
+      this.CorrectClassifiedConfidenceLabel.TabIndex = 3;
+      this.CorrectClassifiedConfidenceLabel.Text = "Conf. Correct Class.:";
+      // 
+      // WrongClassifiedConfidenceLabel
+      // 
+      this.WrongClassifiedConfidenceLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.WrongClassifiedConfidenceLabel.AutoSize = true;
+      this.WrongClassifiedConfidenceLabel.Location = new System.Drawing.Point(455, 7);
+      this.WrongClassifiedConfidenceLabel.Name = "WrongClassifiedConfidenceLabel";
+      this.WrongClassifiedConfidenceLabel.Size = new System.Drawing.Size(101, 13);
+      this.WrongClassifiedConfidenceLabel.TabIndex = 5;
+      this.WrongClassifiedConfidenceLabel.Text = "Conf. Wrong Class.:";
+      // 
+      // CorrectClassifiedConfidence
+      // 
+      this.CorrectClassifiedConfidence.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.CorrectClassifiedConfidence.Location = new System.Drawing.Point(349, 5);
+      this.CorrectClassifiedConfidence.Name = "CorrectClassifiedConfidence";
+      this.CorrectClassifiedConfidence.ReadOnly = true;
+      this.CorrectClassifiedConfidence.Size = new System.Drawing.Size(100, 20);
+      this.CorrectClassifiedConfidence.TabIndex = 7;
+      this.CorrectClassifiedConfidence.Text = "0.0";
+      // 
+      // WrongClassifiedConfidence
+      // 
+      this.WrongClassifiedConfidence.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.WrongClassifiedConfidence.Location = new System.Drawing.Point(562, 4);
+      this.WrongClassifiedConfidence.Name = "WrongClassifiedConfidence";
+      this.WrongClassifiedConfidence.ReadOnly = true;
+      this.WrongClassifiedConfidence.Size = new System.Drawing.Size(94, 20);
+      this.WrongClassifiedConfidence.TabIndex = 8;
+      this.WrongClassifiedConfidence.Text = "0.0";
+      // 
+      // ClassificationEnsembleSolutionEstimatedClassValuesView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.WrongClassifiedConfidence);
+      this.Controls.Add(this.CorrectClassifiedConfidence);
+      this.Controls.Add(this.WrongClassifiedConfidenceLabel);
+      this.Controls.Add(this.CorrectClassifiedConfidenceLabel);
+      this.Controls.Add(this.SamplesComboBox);
+      this.Name = "ClassificationEnsembleSolutionEstimatedClassValuesView";
+      this.Size = new System.Drawing.Size(659, 285);
+      this.Controls.SetChildIndex(this.matrixView, 0);
+      this.Controls.SetChildIndex(this.SamplesComboBox, 0);
+      this.Controls.SetChildIndex(this.CorrectClassifiedConfidenceLabel, 0);
+      this.Controls.SetChildIndex(this.WrongClassifiedConfidenceLabel, 0);
+      this.Controls.SetChildIndex(this.CorrectClassifiedConfidence, 0);
+      this.Controls.SetChildIndex(this.WrongClassifiedConfidence, 0);
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.ComboBox SamplesComboBox;
+    private System.Windows.Forms.Label CorrectClassifiedConfidenceLabel;
+    private System.Windows.Forms.Label WrongClassifiedConfidenceLabel;
+    private System.Windows.Forms.TextBox CorrectClassifiedConfidence;
+    private System.Windows.Forms.TextBox WrongClassifiedConfidence;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionEstimatedClassValuesView.cs	(revision 16097)
@@ -0,0 +1,214 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Estimated Class Values")]
+  [Content(typeof(ClassificationEnsembleSolution))]
+  public partial class ClassificationEnsembleSolutionEstimatedClassValuesView :
+    ClassificationSolutionEstimatedClassValuesView {
+    private const string RowColumnName = "Row";
+    private const string TargetClassValuesColumnName = "Target Variable";
+    private const string EstimatedClassValuesColumnName = "Estimated Class Values";
+    private const string CorrectClassificationColumnName = "Correct Classification";
+    private const string ConfidenceColumnName = "Confidence";
+
+    private const string SamplesComboBoxAllSamples = "All Samples";
+    private const string SamplesComboBoxTrainingSamples = "Training Samples";
+    private const string SamplesComboBoxTestSamples = "Test Samples";
+
+    public new ClassificationEnsembleSolution Content {
+      get { return (ClassificationEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationEnsembleSolutionEstimatedClassValuesView()
+      : base() {
+      InitializeComponent();
+      SamplesComboBox.Items.AddRange(new string[] { SamplesComboBoxAllSamples, SamplesComboBoxTrainingSamples, SamplesComboBoxTestSamples });
+      SamplesComboBox.SelectedIndex = 0;
+      matrixView.DataGridView.RowPrePaint += new DataGridViewRowPrePaintEventHandler(DataGridView_RowPrePaint);
+    }
+
+    private void SamplesComboBox_SelectedIndexChanged(object sender, EventArgs e) {
+      UpdateEstimatedValues();
+    }
+
+    protected override void UpdateEstimatedValues() {
+      if (InvokeRequired) {
+        Invoke((Action)UpdateEstimatedValues);
+        return;
+      }
+      if (Content == null) {
+        matrixView.Content = null;
+        return;
+      }
+
+      int[] indizes;
+      double[] estimatedClassValues;
+
+      switch (SamplesComboBox.SelectedItem.ToString()) {
+        case SamplesComboBoxAllSamples: {
+            indizes = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray();
+            estimatedClassValues = Content.EstimatedClassValues.ToArray();
+            break;
+          }
+        case SamplesComboBoxTrainingSamples: {
+            indizes = Content.ProblemData.TrainingIndices.ToArray();
+            estimatedClassValues = Content.EstimatedTrainingClassValues.ToArray();
+            break;
+          }
+        case SamplesComboBoxTestSamples: {
+            indizes = Content.ProblemData.TestIndices.ToArray();
+            estimatedClassValues = Content.EstimatedTestClassValues.ToArray();
+            break;
+          }
+        default:
+          throw new ArgumentException();
+      }
+
+      IEnumerable<IClassificationSolution> solutions = Content.ClassificationSolutions.CheckedItems;
+      int classValuesCount = Content.ProblemData.Classes;
+      int solutionsCount = solutions.Count();
+      string[,] values = new string[indizes.Length, 5 + classValuesCount + solutionsCount];
+      double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
+      List<List<double?>> estimatedValuesVector = GetEstimatedValues(SamplesComboBox.SelectedItem.ToString(), indizes,
+                                                            solutions);
+
+      IClassificationEnsembleSolutionWeightCalculator weightCalc = Content.WeightCalculator;
+
+      // needed to calculate average confidences of correct and wrong estimated classes
+      bool correctClassified;
+      double[] confidence = new double[2];
+      int[] classified = new int[2];
+      double curConfidence;
+
+      double[] confidences = null;
+
+      if (SamplesComboBox.SelectedItem.ToString().Equals(SamplesComboBoxAllSamples)) {
+        confidences = weightCalc.GetConfidence(solutions,
+                                               indizes,
+                                               estimatedClassValues,
+                                               weightCalc.GetAllClassDelegate()).ToArray();
+      } else if (SamplesComboBox.SelectedItem.ToString().Equals(SamplesComboBoxTrainingSamples)) {
+        confidences = weightCalc.GetConfidence(solutions,
+                                               indizes,
+                                               estimatedClassValues,
+                                               weightCalc.GetTrainingClassDelegate()).ToArray();
+      } else if (SamplesComboBox.SelectedItem.ToString().Equals(SamplesComboBoxTestSamples)) {
+        confidences = weightCalc.GetConfidence(solutions,
+                                               indizes,
+                                               estimatedClassValues,
+                                               weightCalc.GetTestClassDelegate()).ToArray();
+      }
+
+      for (int i = 0; i < indizes.Length; i++) {
+        int row = indizes[i];
+        values[i, 0] = row.ToString();
+        values[i, 1] = target[row].ToString();
+        //display only indices and target values if no models are present
+        if (solutionsCount > 0) {
+          values[i, 2] = estimatedClassValues[i].ToString();
+          correctClassified = target[row].IsAlmost(estimatedClassValues[i]);
+          values[i, 3] = correctClassified.ToString();
+          curConfidence = confidences[i];
+          if (correctClassified) {
+            confidence[0] += curConfidence;
+            classified[0]++;
+          } else {
+            confidence[1] += curConfidence;
+            classified[1]++;
+          }
+
+          values[i, 4] = curConfidence.ToString();
+
+          var groups =
+            estimatedValuesVector[i].GroupBy(x => x).Select(g => new { Key = g.Key, Count = g.Count() }).ToList();
+
+          for (int classIndex = 0; classIndex < Content.ProblemData.Classes; classIndex++) {
+            var group = groups.Where(g => g.Key == Content.ProblemData.ClassValues.ElementAt(classIndex)).SingleOrDefault();
+            if (group == null) values[i, 5 + classIndex] = 0.ToString();
+            else values[i, 5 + classIndex] = group.Count.ToString();
+          }
+          for (int modelIndex = 0; modelIndex < estimatedValuesVector[i].Count; modelIndex++) {
+            values[i, 5 + classValuesCount + modelIndex] = estimatedValuesVector[i][modelIndex] == null
+                                                             ? string.Empty
+                                                             : estimatedValuesVector[i][modelIndex].ToString();
+          }
+        }
+      }
+
+      CorrectClassifiedConfidence.Text = (confidence[0] / (double)classified[0]).ToString();
+      WrongClassifiedConfidence.Text = (confidence[1] / (double)classified[1]).ToString();
+
+      StringMatrix matrix = new StringMatrix(values);
+      List<string> columnNames = new List<string>() { "Id", TargetClassValuesColumnName, EstimatedClassValuesColumnName, CorrectClassificationColumnName, ConfidenceColumnName };
+      columnNames.AddRange(Content.ProblemData.ClassNames);
+      columnNames.AddRange(Content.ClassificationSolutions.CheckedItems.Select(s => s.Model.Name));//.Model.Models.Select(m => m.Name));
+      matrix.ColumnNames = columnNames;
+      matrix.SortableView = true;
+      matrixView.Content = matrix;
+    }
+
+    private List<List<double?>> GetEstimatedValues(string samplesSelection, int[] rows, IEnumerable<IClassificationSolution> solutions) {
+      List<List<double?>> values = new List<List<double?>>();
+      int solutionIndex = 0;
+      foreach (var solution in solutions) {
+        double[] estimation = solution.GetEstimatedClassValues(rows).ToArray();
+        for (int i = 0; i < rows.Length; i++) {
+          var row = rows[i];
+          if (solutionIndex == 0) values.Add(new List<double?>());
+
+          if (samplesSelection == SamplesComboBoxAllSamples)
+            values[i].Add(estimation[i]);
+          else if (samplesSelection == SamplesComboBoxTrainingSamples && solution.ProblemData.IsTrainingSample(row))
+            values[i].Add(estimation[i]);
+          else if (samplesSelection == SamplesComboBoxTestSamples && solution.ProblemData.IsTestSample(row))
+            values[i].Add(estimation[i]);
+          else
+            values[i].Add(null);
+        }
+        solutionIndex++;
+      }
+      return values;
+    }
+
+    private void DataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler<DataGridViewRowPrePaintEventArgs>(DataGridView_RowPrePaint), sender, e);
+        return;
+      }
+      var cellValue = matrixView.DataGridView[3, e.RowIndex].Value.ToString();
+      if (string.IsNullOrEmpty(cellValue)) return;
+      bool correctClassified = bool.Parse(cellValue);
+      matrixView.DataGridView.Rows[e.RowIndex].DefaultCellStyle.ForeColor = correctClassified ? Color.MediumSeaGreen : Color.Red;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.Designer.cs	(revision 16097)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationEnsembleSolutionModelView {
+    /// <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() {
+      this.SuspendLayout();
+
+      // 
+      // RegressionSolutionEnsembleModelView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "RegressionEnsembleSolutionModelView";
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationEnsembleSolutionModelView.cs	(revision 16097)
@@ -0,0 +1,91 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Ensemble Solutions")]
+  [Content(typeof(ClassificationEnsembleSolution), false)]
+  internal sealed partial class ClassificationEnsembleSolutionModelView : DataAnalysisSolutionEvaluationView {
+    private ModelsView view;
+
+    public ClassificationEnsembleSolutionModelView() {
+      InitializeComponent();
+      view = new ModelsView();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
+    }
+
+    public new ClassificationEnsembleSolution Content {
+      get { return (ClassificationEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        view.Locked = Content.ProblemData == ClassificationEnsembleProblemData.EmptyProblemData;
+        view.Content = Content.ClassificationSolutions;
+      } else
+        view.Content = null;
+    }
+
+    public override System.Drawing.Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Properties; }
+    }
+
+    private class ModelsView : CheckedItemCollectionView<IClassificationSolution> {
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
+        removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
+        itemsListView.Enabled = Content != null;
+        detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+      }
+
+      protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+        validDragOperation = false;
+        if (ReadOnly || Locked) return;
+        if (Content.IsReadOnly) return;
+
+        var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        validDragOperation = dropData.GetObjectGraphObjects().OfType<IClassificationSolution>().Any();
+      }
+      protected override void itemsListView_DragDrop(object sender, DragEventArgs e) {
+        if (e.Effect != DragDropEffects.None) {
+          var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          var solutions = dropData.GetObjectGraphObjects().OfType<IClassificationSolution>();
+          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
+            Cloner cloner = new Cloner();
+            solutions = solutions.Select(s => cloner.Clone(s));
+          }
+          foreach (var solution in solutions)
+            Content.Add(solution);
+        }
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationFeatureCorrelationView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Classification Feature Correlation View")]
+  [Content(typeof(ClassificationProblemData), false)]
+  public partial class ClassificationFeatureCorrelationView : FeatureCorrelationView {
+
+    public new ClassificationProblemData Content {
+      get { return (ClassificationProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVariableVisibility() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVariableVisibility();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.Designer.cs	(revision 16097)
@@ -0,0 +1,86 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationSolutionConfusionMatrixView {
+    /// <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() {
+      this.dataGridView = new System.Windows.Forms.DataGridView();
+      this.cmbSamples = new System.Windows.Forms.ComboBox();
+      this.label1 = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // dataGridView
+      // 
+      this.dataGridView.AllowUserToAddRows = false;
+      this.dataGridView.AllowUserToDeleteRows = false;
+      this.dataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      this.dataGridView.Location = new System.Drawing.Point(3, 30);
+      this.dataGridView.Name = "dataGridView";
+      this.dataGridView.ReadOnly = true;
+      this.dataGridView.Size = new System.Drawing.Size(303, 197);
+      this.dataGridView.TabIndex = 0;
+      // 
+      // cmbSamples
+      // 
+      this.cmbSamples.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbSamples.FormattingEnabled = true;
+      this.cmbSamples.Location = new System.Drawing.Point(56, 3);
+      this.cmbSamples.Name = "cmbSamples";
+      this.cmbSamples.Size = new System.Drawing.Size(121, 21);
+      this.cmbSamples.TabIndex = 1;
+      this.cmbSamples.SelectedIndexChanged += new System.EventHandler(this.cmbSamples_SelectedIndexChanged);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(47, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "Samples";
+      // 
+      // ConfusionMatrixView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.cmbSamples);
+      this.Controls.Add(this.dataGridView);
+      this.Name = "ConfusionMatrixView";
+      this.Size = new System.Drawing.Size(309, 230);
+      ((System.ComponentModel.ISupportInitialize)(this.dataGridView)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.DataGridView dataGridView;
+    private System.Windows.Forms.ComboBox cmbSamples;
+    private System.Windows.Forms.Label label1;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionConfusionMatrixView.cs	(revision 16097)
@@ -0,0 +1,153 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Confusion Matrix")]
+  [Content(typeof(IClassificationSolution))]
+  public partial class ClassificationSolutionConfusionMatrixView : DataAnalysisSolutionEvaluationView {
+    private const string TrainingSamples = "Training";
+    private const string TestSamples = "Test";
+    public ClassificationSolutionConfusionMatrixView() {
+      InitializeComponent();
+      cmbSamples.Items.Add(TrainingSamples);
+      cmbSamples.Items.Add(TestSamples);
+      cmbSamples.SelectedIndex = 0;
+    }
+
+    public new IClassificationSolution Content {
+      get { return (IClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      FillDataGridView();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      UpdateDataGridView();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateDataGridView();
+    }
+
+    private void UpdateDataGridView() {
+      if (InvokeRequired) Invoke((Action)UpdateDataGridView);
+      else {
+        if (Content == null) {
+          dataGridView.RowCount = 1;
+          dataGridView.ColumnCount = 1;
+        } else {
+          dataGridView.ColumnCount = Content.ProblemData.Classes + 1;
+          dataGridView.RowCount = Content.ProblemData.Classes + 1;
+
+          int i = 0;
+          foreach (string headerText in Content.ProblemData.ClassNames) {
+            dataGridView.Columns[i].HeaderText = "Actual " + headerText;
+            dataGridView.Rows[i].HeaderCell.Value = "Predicted " + headerText;
+            i++;
+          }
+          dataGridView.Columns[i].HeaderText = "Actual not classified";
+          dataGridView.Rows[i].HeaderCell.Value = "Predicted not classified";
+
+          dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.ColumnHeader);
+          dataGridView.AutoResizeRowHeadersWidth(DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);
+
+          FillDataGridView();
+        }
+      }
+    }
+
+    private void FillDataGridView() {
+      if (InvokeRequired) Invoke((Action)FillDataGridView);
+      else {
+        if (Content == null) return;
+
+        double[,] confusionMatrix = new double[Content.ProblemData.Classes + 1, Content.ProblemData.Classes + 1];
+        IEnumerable<int> rows;
+
+        double[] predictedValues;
+        if (cmbSamples.SelectedItem.ToString() == TrainingSamples) {
+          rows = Content.ProblemData.TrainingIndices;
+          predictedValues = Content.EstimatedTrainingClassValues.ToArray();
+        } else if (cmbSamples.SelectedItem.ToString() == TestSamples) {
+          rows = Content.ProblemData.TestIndices;
+          predictedValues = Content.EstimatedTestClassValues.ToArray();
+        } else throw new InvalidOperationException();
+
+        double[] targetValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable, rows).ToArray();
+
+        Dictionary<double, int> classValueIndexMapping = new Dictionary<double, int>();
+        int index = 0;
+        foreach (double classValue in Content.ProblemData.ClassValues.OrderBy(x => x)) {
+          classValueIndexMapping.Add(classValue, index);
+          index++;
+        }
+
+        for (int i = 0; i < targetValues.Length; i++) {
+          double targetValue = targetValues[i];
+          double predictedValue = predictedValues[i];
+          int targetIndex;
+          int predictedIndex;
+          if (!classValueIndexMapping.TryGetValue(targetValue, out targetIndex)) {
+            targetIndex = Content.ProblemData.Classes;
+          }
+          if (!classValueIndexMapping.TryGetValue(predictedValue, out predictedIndex)) {
+            predictedIndex = Content.ProblemData.Classes;
+          }
+
+          confusionMatrix[predictedIndex, targetIndex] += 1;
+        }
+
+        for (int row = 0; row < confusionMatrix.GetLength(0); row++) {
+          for (int col = 0; col < confusionMatrix.GetLength(1); col++) {
+            //TODO add scaling to relative values;
+            dataGridView[col, row].Value = confusionMatrix[row, col];
+          }
+        }
+      }
+    }
+
+    private void cmbSamples_SelectedIndexChanged(object sender, System.EventArgs e) {
+      FillDataGridView();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationSolutionEstimatedClassValuesView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // EstimatedValuesView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EstimatedValuesView";
+      this.Size = new System.Drawing.Size(310, 285);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationSolutionEstimatedClassValuesView.cs	(revision 16097)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Estimated Class Values")]
+  [Content(typeof(IClassificationSolution))]
+  public partial class ClassificationSolutionEstimatedClassValuesView : DataAnalysisSolutionEvaluationView {
+    private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
+    private const string ESTIMATEDVALUES_SERIES_NAME = "Estimated Class Values (all)";
+    private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Class Values (training)";
+    private const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Class Values (test)";
+
+    public new IClassificationSolution Content {
+      get { return (IClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected StringConvertibleMatrixView matrixView;
+
+    public ClassificationSolutionEstimatedClassValuesView()
+      : base() {
+      InitializeComponent();
+      matrixView = new StringConvertibleMatrixView();
+      matrixView.ShowRowsAndColumnsTextBox = false;
+      matrixView.ShowStatisticalInformation = false;
+      matrixView.Dock = DockStyle.Fill;
+      this.Controls.Add(matrixView);
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateEstimatedValues();
+    }
+
+    protected virtual void UpdateEstimatedValues() {
+      if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
+      else {
+        StringMatrix matrix = null;
+        if (Content != null) {
+          string[,] values = new string[Content.ProblemData.Dataset.Rows, 5];
+
+          double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
+          double[] estimated = Content.EstimatedClassValues.ToArray();
+          for (int row = 0; row < target.Length; row++) {
+            values[row, 0] = row.ToString();
+            values[row, 1] = target[row].ToString();
+            values[row, 2] = estimated[row].ToString();
+          }
+
+          var estimatedTraining = Content.EstimatedTrainingClassValues.GetEnumerator();
+          estimatedTraining.MoveNext();
+          foreach (var trainingRow in Content.ProblemData.TrainingIndices) {
+            values[trainingRow, 3] = estimatedTraining.Current.ToString();
+            estimatedTraining.MoveNext();
+          }
+          var estimatedTest = Content.EstimatedTestClassValues.GetEnumerator();
+          estimatedTest.MoveNext();
+          foreach (var testRow in Content.ProblemData.TestIndices) {
+            values[testRow, 4] = estimatedTest.Current.ToString();
+            estimatedTest.MoveNext();
+          }
+
+          matrix = new StringMatrix(values);
+          matrix.ColumnNames = new string[] { "Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME };
+          matrix.SortableView = true;
+        }
+        matrixView.Content = matrix;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationTimeframeFeatureCorrelationView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/ClassificationTimeframeFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Classification Timeframe Feature Correlation View")]
+  [Content(typeof(ClassificationProblemData), false)]
+  public partial class ClassificationTimeframeFeatureCorrelationView : TimeframeFeatureCorrelationView {
+
+    public new ClassificationProblemData Content {
+      get { return (ClassificationProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClassificationTimeframeFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVariableVisibility() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVariableVisibility();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.Designer.cs	(revision 16097)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationModelView {
+    /// <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() {
+      this.SuspendLayout();
+
+      // 
+      // RegressionSolutionEnsembleModelView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "DiscriminantFunctionClassificationModelView";
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationModelView.cs	(revision 16097)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Discriminant Function Classification Model")]
+  [Content(typeof(DiscriminantFunctionClassificationModel), true)]
+  internal sealed partial class DiscriminantFunctionClassificationModelView : AsynchronousContentView {
+    private ViewHost view;
+
+    public DiscriminantFunctionClassificationModelView() {
+      InitializeComponent();
+      view = new ViewHost();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
+    }
+
+    public new DiscriminantFunctionClassificationModel Content {
+      get { return (DiscriminantFunctionClassificationModel)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        view.Content = Content.Model;
+      } else
+        view.Content = null;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.Designer.cs	(revision 16097)
@@ -0,0 +1,98 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationRocCurvesView {
+    /// <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() {
+      this.components = new System.ComponentModel.Container();
+      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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.label1 = new System.Windows.Forms.Label();
+      this.cmbSamples = new System.Windows.Forms.ComboBox();
+      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(0, 28);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(366, 202);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(47, 13);
+      this.label1.TabIndex = 4;
+      this.label1.Text = "Samples";
+      // 
+      // cmbSamples
+      // 
+      this.cmbSamples.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbSamples.FormattingEnabled = true;
+      this.cmbSamples.Location = new System.Drawing.Point(56, 3);
+      this.cmbSamples.Name = "cmbSamples";
+      this.cmbSamples.Size = new System.Drawing.Size(121, 21);
+      this.cmbSamples.TabIndex = 3;
+      this.cmbSamples.SelectedIndexChanged += new System.EventHandler(this.cmbSamples_SelectedIndexChanged);
+      // 
+      // RocCurvesView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.cmbSamples);
+      this.Controls.Add(this.chart);
+      this.Name = "RocCurvesView";
+      this.Size = new System.Drawing.Size(366, 230);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.Label label1;
+    private System.Windows.Forms.ComboBox cmbSamples;
+    private System.Windows.Forms.ToolTip toolTip;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationRocCurvesView.cs	(revision 16097)
@@ -0,0 +1,264 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ROC Curves")]
+  [Content(typeof(IDiscriminantFunctionClassificationSolution))]
+  public partial class DiscriminantFunctionClassificationRocCurvesView : DataAnalysisSolutionEvaluationView {
+    private const string xAxisTitle = "False Positive Rate";
+    private const string yAxisTitle = "True Positive Rate";
+    private const string TrainingSamples = "Training";
+    private const string TestSamples = "Test";
+    private Dictionary<string, List<ROCPoint>> cachedRocPoints;
+
+    public DiscriminantFunctionClassificationRocCurvesView() {
+      InitializeComponent();
+
+      cachedRocPoints = new Dictionary<string, List<ROCPoint>>();
+
+      cmbSamples.Items.Add(TrainingSamples);
+      cmbSamples.Items.Add(TestSamples);
+      cmbSamples.SelectedIndex = 0;
+
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].AxisX.Minimum = 0.0;
+      chart.ChartAreas[0].AxisX.Maximum = 1.0;
+      chart.ChartAreas[0].AxisX.MajorGrid.Interval = 0.2;
+      chart.ChartAreas[0].AxisY.Minimum = 0.0;
+      chart.ChartAreas[0].AxisY.Maximum = 1.0;
+      chart.ChartAreas[0].AxisY.MajorGrid.Interval = 0.2;
+
+      chart.ChartAreas[0].AxisX.Title = xAxisTitle;
+      chart.ChartAreas[0].AxisY.Title = yAxisTitle;
+    }
+
+    public new IDiscriminantFunctionClassificationSolution Content {
+      get { return (IDiscriminantFunctionClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      UpdateChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      UpdateChart();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      chart.Series.Clear();
+      if (Content != null) UpdateChart();
+    }
+
+    private void UpdateChart() {
+      if (InvokeRequired) Invoke((Action)UpdateChart);
+      else {
+        chart.Series.Clear();
+        chart.Annotations.Clear();
+        cachedRocPoints.Clear();
+
+        int slices = 100;
+        IEnumerable<int> rows;
+
+        if (cmbSamples.SelectedItem.ToString() == TrainingSamples) {
+          rows = Content.ProblemData.TrainingIndices;
+        } else if (cmbSamples.SelectedItem.ToString() == TestSamples) {
+          rows = Content.ProblemData.TestIndices;
+        } else throw new InvalidOperationException();
+
+        double[] estimatedValues = Content.GetEstimatedValues(rows).ToArray();
+        double[] targetClassValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable, rows).ToArray();
+        double minThreshold = estimatedValues.Min();
+        double maxThreshold = estimatedValues.Max();
+        double thresholdIncrement = (maxThreshold - minThreshold) / slices;
+        minThreshold -= thresholdIncrement;
+        maxThreshold += thresholdIncrement;
+
+        List<double> classValues = Content.ProblemData.ClassValues.ToList();
+
+        foreach (double classValue in classValues) {
+          List<ROCPoint> rocPoints = new List<ROCPoint>();
+          int positives = targetClassValues.Where(c => c.IsAlmost(classValue)).Count();
+          int negatives = targetClassValues.Length - positives;
+
+          for (double lowerThreshold = minThreshold; lowerThreshold < maxThreshold; lowerThreshold += thresholdIncrement) {
+            for (double upperThreshold = lowerThreshold + thresholdIncrement; upperThreshold < maxThreshold; upperThreshold += thresholdIncrement) {
+              //only adapt lower threshold for binary classification problems and upper class prediction              
+              if (classValues.Count == 2 && classValue == classValues[1]) upperThreshold = double.PositiveInfinity;
+
+              int truePositives = 0;
+              int falsePositives = 0;
+
+              for (int row = 0; row < estimatedValues.Length; row++) {
+                if (lowerThreshold < estimatedValues[row] && estimatedValues[row] < upperThreshold) {
+                  if (targetClassValues[row].IsAlmost(classValue)) truePositives++;
+                  else falsePositives++;
+                }
+              }
+
+              double truePositiveRate = ((double)truePositives) / positives;
+              double falsePositiveRate = ((double)falsePositives) / negatives;
+
+              ROCPoint rocPoint = new ROCPoint(truePositiveRate, falsePositiveRate, lowerThreshold, upperThreshold);
+              if (!rocPoints.Any(x => x.TruePositiveRate >= rocPoint.TruePositiveRate && x.FalsePositiveRate <= rocPoint.FalsePositiveRate)) {
+                rocPoints.RemoveAll(x => x.FalsePositiveRate >= rocPoint.FalsePositiveRate && x.TruePositiveRate <= rocPoint.TruePositiveRate);
+                rocPoints.Add(rocPoint);
+              }
+            }
+            //only adapt upper threshold for binary classification problems and upper class prediction              
+            if (classValues.Count == 2 && classValue == classValues[0]) lowerThreshold = double.PositiveInfinity;
+          }
+
+          string className = Content.ProblemData.ClassNames.ElementAt(classValues.IndexOf(classValue));
+          cachedRocPoints[className] = rocPoints.OrderBy(x => x.FalsePositiveRate).ToList(); ;
+
+          Series series = new Series(className);
+          series.ChartType = SeriesChartType.Line;
+          series.MarkerStyle = MarkerStyle.Diamond;
+          series.MarkerSize = 5;
+          chart.Series.Add(series);
+          FillSeriesWithDataPoints(series, cachedRocPoints[className]);
+
+          double auc = CalculateAreaUnderCurve(series);
+          series.LegendToolTip = "AUC: " + auc;
+        }
+      }
+    }
+
+    private void FillSeriesWithDataPoints(Series series, IEnumerable<ROCPoint> rocPoints) {
+      series.Points.Add(new DataPoint(0, 0));
+      foreach (ROCPoint rocPoint in rocPoints) {
+        DataPoint point = new DataPoint();
+        point.XValue = rocPoint.FalsePositiveRate;
+        point.YValues[0] = rocPoint.TruePositiveRate;
+        point.Tag = rocPoint;
+
+        StringBuilder sb = new StringBuilder();
+        sb.AppendLine("True Positive Rate: " + rocPoint.TruePositiveRate);
+        sb.AppendLine("False Positive Rate: " + rocPoint.FalsePositiveRate);
+        sb.AppendLine("Upper Threshold: " + rocPoint.UpperThreshold);
+        sb.AppendLine("Lower Threshold: " + rocPoint.LowerThreshold);
+        point.ToolTip = sb.ToString();
+
+        series.Points.Add(point);
+      }
+      series.Points.Add(new DataPoint(1, 1));
+    }
+
+    private double CalculateAreaUnderCurve(Series series) {
+      if (series.Points.Count < 1) throw new ArgumentException("Could not calculate area under curve if less than 1 data points were given.");
+
+      double auc = 0.0;
+      for (int i = 1; i < series.Points.Count; i++) {
+        double width = series.Points[i].XValue - series.Points[i - 1].XValue;
+        double y1 = series.Points[i - 1].YValues[0];
+        double y2 = series.Points[i].YValues[0];
+
+        auc += (y1 + y2) * width / 2;
+      }
+
+      return auc;
+    }
+
+    private void cmbSamples_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (Content != null)
+        UpdateChart();
+    }
+
+
+    #region show / hide series
+    private void ToggleSeries(Series series) {
+      if (series.Points.Count == 0)
+        FillSeriesWithDataPoints(series, cachedRocPoints[series.Name]);
+      else
+        series.Points.Clear();
+    }
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        if (result.Series != null) ToggleSeries(result.Series);
+      }
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = series.Points.Count == 0;
+          foreach (LegendCell cell in legendItem.Cells)
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+        }
+      }
+    }
+    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;
+
+      string newTooltipText = string.Empty;
+      if (result.ChartElementType == ChartElementType.DataPoint)
+        newTooltipText = ((DataPoint)result.Object).ToolTip;
+
+      string oldTooltipText = this.toolTip.GetToolTip(chart);
+      if (newTooltipText != oldTooltipText)
+        this.toolTip.SetToolTip(chart, newTooltipText);
+    }
+    #endregion
+
+
+    private class ROCPoint {
+      public ROCPoint(double truePositiveRate, double falsePositiveRate, double lowerThreshold, double upperThreshold) {
+        this.TruePositiveRate = truePositiveRate;
+        this.FalsePositiveRate = falsePositiveRate;
+        this.LowerThreshold = lowerThreshold;
+        this.UpperThreshold = upperThreshold;
+
+      }
+      public double TruePositiveRate { get; private set; }
+      public double FalsePositiveRate { get; private set; }
+      public double LowerThreshold { get; private set; }
+      public double UpperThreshold { get; private set; }
+    }
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs	(revision 16097)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationSolutionEstimatedClassValuesView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // EstimatedValuesView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EstimatedValuesView";
+      this.Size = new System.Drawing.Size(310, 285);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs	(revision 16097)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Estimated Class Values")]
+  [Content(typeof(IDiscriminantFunctionClassificationSolution))]
+  public partial class DiscriminantFunctionClassificationSolutionEstimatedClassValuesView : ClassificationSolutionEstimatedClassValuesView {
+    private const string TargetClassValuesSeriesname = "TargetVariable";
+    private const string EstimatedClassValuesSeriesName = "EstimatedClassValues";
+    private const string EstimatedValuesSeriesName = "EstimatedValues";
+
+    public new IDiscriminantFunctionClassificationSolution Content {
+      get { return (IDiscriminantFunctionClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DiscriminantFunctionClassificationSolutionEstimatedClassValuesView()
+      : base() {
+      InitializeComponent();
+    }
+
+    protected override void UpdateEstimatedValues() {
+      if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
+      else {
+        StringMatrix matrix = null;
+        if (Content != null) {
+          string[,] values = new string[Content.ProblemData.Dataset.Rows, 4];
+
+          double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
+          double[] estimatedClassValues = Content.EstimatedClassValues.ToArray();
+          double[] estimatedValues = Content.EstimatedValues.ToArray();
+          for (int row = 0; row < target.Length; row++) {
+            values[row, 0] = row.ToString();
+            values[row, 1] = target[row].ToString();
+            values[row, 2] = estimatedClassValues[row].ToString();
+            values[row, 3] = estimatedValues[row].ToString();
+          }
+
+          matrix = new StringMatrix(values);
+          matrix.ColumnNames = new string[] { "Id", TargetClassValuesSeriesname, EstimatedClassValuesSeriesName, EstimatedValuesSeriesName };
+          matrix.SortableView = true;
+        }
+        matrixView.Content = matrix;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs	(revision 16097)
@@ -0,0 +1,102 @@
+﻿using System.Windows.Forms.DataVisualization.Charting;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationSolutionThresholdView {
+    /// <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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.JitterTrackBar = new System.Windows.Forms.TrackBar();
+      this.label1 = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.JitterTrackBar)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(3, 3);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(553, 364);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.AnnotationPositionChanging += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.AnnotationPositionChangingEventArgs>(this.chart_AnnotationPositionChanging);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      this.chart.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(chart_PostPaint);
+      // 
+      // JitterTrackBar
+      // 
+      this.JitterTrackBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.JitterTrackBar.BackColor = System.Drawing.SystemColors.Window;
+      this.JitterTrackBar.Location = new System.Drawing.Point(483, 341);
+      this.JitterTrackBar.Maximum = 100;
+      this.JitterTrackBar.Name = "JitterTrackBar";
+      this.JitterTrackBar.Size = new System.Drawing.Size(71, 45);
+      this.JitterTrackBar.TabIndex = 1;
+      this.JitterTrackBar.TickStyle = System.Windows.Forms.TickStyle.None;
+      this.JitterTrackBar.ValueChanged += new System.EventHandler(this.JitterTrackBar_ValueChanged);
+      // 
+      // label1
+      // 
+      this.label1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.label1.AutoSize = true;
+      this.label1.BackColor = System.Drawing.SystemColors.Window;
+      this.label1.Location = new System.Drawing.Point(448, 345);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(32, 13);
+      this.label1.TabIndex = 2;
+      this.label1.Text = "Jitter:";
+      // 
+      // SymbolicClassificationSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.JitterTrackBar);
+      this.Controls.Add(this.chart);
+      this.Name = "SymbolicClassificationSolutionView";
+      this.Size = new System.Drawing.Size(559, 370);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.JitterTrackBar)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    private System.Windows.Forms.TrackBar JitterTrackBar;
+    private System.Windows.Forms.Label label1;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Classification/DiscriminantFunctionClassificationSolutionThresholdView.cs	(revision 16097)
@@ -0,0 +1,325 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Classification Threshold")]
+  [Content(typeof(IDiscriminantFunctionClassificationSolution), false)]
+  public sealed partial class DiscriminantFunctionClassificationSolutionThresholdView : DataAnalysisSolutionEvaluationView {
+    private const double TrainingAxisValue = 0.0;
+    private const double TestAxisValue = 10.0;
+    private const double TrainingTestBorder = (TestAxisValue - TrainingAxisValue) / 2;
+    private const string TrainingLabelText = "Training Samples";
+    private const string TestLabelText = "Test Samples";
+
+    private const double ClassNameLeftOffset = 10.0;
+    private const double ClassNameBottomOffset = 5.0;
+
+    public new IDiscriminantFunctionClassificationSolution Content {
+      get { return (IDiscriminantFunctionClassificationSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    private Dictionary<double, Series> classValueSeriesMapping;
+    private Random random;
+    private bool updateInProgress, updateThresholds;
+
+    public DiscriminantFunctionClassificationSolutionThresholdView()
+      : base() {
+      InitializeComponent();
+
+      classValueSeriesMapping = new Dictionary<double, Series>();
+      random = new Random();
+      updateInProgress = false;
+
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisX.Minimum = TrainingAxisValue - TrainingTestBorder;
+      this.chart.ChartAreas[0].AxisX.Maximum = TestAxisValue + TrainingTestBorder;
+      AddCustomLabelToAxis(this.chart.ChartAreas[0].AxisX);
+
+      this.chart.ChartAreas[0].AxisY.Title = "Estimated Values";
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+    }
+
+    private void AddCustomLabelToAxis(Axis axis) {
+      CustomLabel trainingLabel = new CustomLabel();
+      trainingLabel.Text = TrainingLabelText;
+      trainingLabel.FromPosition = TrainingAxisValue - TrainingTestBorder;
+      trainingLabel.ToPosition = TrainingAxisValue + TrainingTestBorder;
+      axis.CustomLabels.Add(trainingLabel);
+
+      CustomLabel testLabel = new CustomLabel();
+      testLabel.Text = TestLabelText;
+      testLabel.FromPosition = TestAxisValue - TrainingTestBorder;
+      testLabel.ToPosition = TestAxisValue + TrainingTestBorder;
+      axis.CustomLabels.Add(testLabel);
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      UpdateChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      Content.Model.ThresholdsChanged += new EventHandler(Model_ThresholdsChanged);
+      UpdateChart();
+    }
+    private void Model_ThresholdsChanged(object sender, EventArgs e) {
+      AddThresholds();
+    }
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    private void UpdateChart() {
+      if (InvokeRequired) Invoke((Action)UpdateChart);
+      else if (!updateInProgress) {
+        updateInProgress = true;
+        chart.Series.Clear();
+        classValueSeriesMapping.Clear();
+        if (Content != null) {
+          IEnumerator<string> classNameEnumerator = Content.ProblemData.ClassNames.GetEnumerator();
+          IEnumerator<double> classValueEnumerator = Content.ProblemData.ClassValues.OrderBy(x => x).GetEnumerator();
+          while (classNameEnumerator.MoveNext() && classValueEnumerator.MoveNext()) {
+            Series series = new Series(classNameEnumerator.Current);
+            series.ChartType = SeriesChartType.FastPoint;
+            series.Tag = classValueEnumerator.Current;
+            chart.Series.Add(series);
+            classValueSeriesMapping.Add(classValueEnumerator.Current, series);
+            FillSeriesWithDataPoints(series);
+          }
+          updateThresholds = true;
+        }
+        chart.ChartAreas[0].RecalculateAxesScale();
+        updateInProgress = false;
+      }
+    }
+
+    private void FillSeriesWithDataPoints(Series series) {
+      List<double> estimatedValues = Content.EstimatedValues.ToList();
+      var targetValues = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToList();
+
+      foreach (int row in Content.ProblemData.TrainingIndices) {
+        double estimatedValue = estimatedValues[row];
+        double targetValue = targetValues[row];
+        if (targetValue.IsAlmost((double)series.Tag)) {
+          double jitterValue = random.NextDouble() * 2.0 - 1.0;
+          DataPoint point = new DataPoint();
+          point.XValue = TrainingAxisValue + 0.01 * jitterValue * JitterTrackBar.Value * (TrainingTestBorder * 0.9);
+          point.YValues[0] = estimatedValue;
+          point.Tag = new KeyValuePair<double, double>(TrainingAxisValue, jitterValue);
+          series.Points.Add(point);
+        }
+      }
+
+      foreach (int row in Content.ProblemData.TestIndices) {
+        double estimatedValue = estimatedValues[row];
+        double targetValue = targetValues[row];
+        if (targetValue.IsAlmost((double)series.Tag)) {
+          double jitterValue = random.NextDouble() * 2.0 - 1.0;
+          DataPoint point = new DataPoint();
+          point.XValue = TestAxisValue + 0.01 * jitterValue * JitterTrackBar.Value * (TrainingTestBorder * 0.9);
+          point.YValues[0] = estimatedValue;
+          point.Tag = new KeyValuePair<double, double>(TestAxisValue, jitterValue);
+          series.Points.Add(point);
+        }
+      }
+
+      UpdateCursorInterval();
+    }
+
+    private void chart_PostPaint(object sender, ChartPaintEventArgs e) {
+      if (updateThresholds) {
+        AddThresholds();
+        updateThresholds = false;
+      }
+    }
+
+    private void AddThresholds() {
+      chart.Annotations.Clear();
+      int classIndex = 1;
+      SizeF textSizeInPixel;
+      IClassificationProblemData problemData = Content.ProblemData;
+      var classValues = Content.Model.ClassValues.ToArray();
+      Graphics g = chart.CreateGraphics();
+      Axis y = chart.ChartAreas[0].AxisY;
+      Axis x = chart.ChartAreas[0].AxisX;
+      string name;
+      foreach (double threshold in Content.Model.Thresholds) {
+        if (!double.IsInfinity(threshold)) {
+          HorizontalLineAnnotation annotation = new HorizontalLineAnnotation();
+          annotation.AllowMoving = true;
+          annotation.AllowResizing = false;
+          annotation.LineWidth = 2;
+          annotation.LineColor = Color.Red;
+          annotation.IsInfinitive = true;
+          annotation.ClipToChartArea = chart.ChartAreas[0].Name;
+          annotation.Tag = classIndex;  //save classIndex as Tag to avoid moving the threshold accross class bounderies
+          annotation.AxisX = chart.ChartAreas[0].AxisX;
+          annotation.AxisY = y;
+          annotation.Y = threshold;
+
+          name = problemData.GetClassName(classValues[classIndex - 1]);
+          TextAnnotation beneathLeft = CreateTextAnnotation(name, classIndex, x, y);
+          beneathLeft.Y = threshold;
+          beneathLeft.X = x.Minimum;
+          TextAnnotation beneathRigth = CreateTextAnnotation(name, classIndex, x, y);
+          beneathRigth.Y = threshold;
+          textSizeInPixel = g.MeasureString(beneathRigth.Text, beneathRigth.Font);
+          double textWidthPixelPos = x.ValueToPixelPosition(x.Maximum) - textSizeInPixel.Width - ClassNameLeftOffset;
+          //check if position is within the position boundary
+          beneathRigth.X = textWidthPixelPos < 0 || textWidthPixelPos > chart.Width ? double.NaN : x.PixelPositionToValue(textWidthPixelPos);
+
+          name = problemData.GetClassName(classValues[classIndex]);
+          TextAnnotation aboveLeft = CreateTextAnnotation(name, classIndex, x, y);
+          textSizeInPixel = g.MeasureString(aboveLeft.Text, aboveLeft.Font);
+          double textHeightPixelPos = y.ValueToPixelPosition(threshold) - textSizeInPixel.Height - ClassNameBottomOffset;
+          //check if position is within the position boundary
+          aboveLeft.Y = textHeightPixelPos < 0 || textHeightPixelPos > chart.Height ? double.NaN : y.PixelPositionToValue(textHeightPixelPos);
+          aboveLeft.X = x.Minimum;
+          TextAnnotation aboveRight = CreateTextAnnotation(name, classIndex, x, y);
+          aboveRight.Y = aboveLeft.Y;
+          textWidthPixelPos = x.ValueToPixelPosition(x.Maximum) - textSizeInPixel.Width - ClassNameLeftOffset;
+          //check if position is within the position boundary
+          aboveRight.X = textWidthPixelPos < 0 || textWidthPixelPos > chart.Width ? double.NaN : x.PixelPositionToValue(textWidthPixelPos);
+
+          chart.Annotations.Add(annotation);
+          chart.Annotations.Add(beneathLeft);
+          chart.Annotations.Add(aboveLeft);
+          chart.Annotations.Add(beneathRigth);
+          chart.Annotations.Add(aboveRight);
+          classIndex++;
+        }
+      }
+    }
+
+    private TextAnnotation CreateTextAnnotation(string name, int classIndex, Axis x, Axis y) {
+      TextAnnotation annotation = new TextAnnotation();
+      annotation.Text = name;
+      annotation.AllowMoving = true;
+      annotation.AllowResizing = false;
+      annotation.AllowSelecting = false;
+      annotation.ClipToChartArea = chart.ChartAreas[0].Name;
+      annotation.Tag = classIndex;
+      annotation.AxisX = chart.ChartAreas[0].AxisX;
+      annotation.AxisY = y;
+      return annotation;
+    }
+
+    private void JitterTrackBar_ValueChanged(object sender, EventArgs e) {
+      foreach (Series series in chart.Series) {
+        foreach (DataPoint point in series.Points) {
+          double value = ((KeyValuePair<double, double>)point.Tag).Key;
+          double jitterValue = ((KeyValuePair<double, double>)point.Tag).Value; ;
+          point.XValue = value + 0.01 * jitterValue * JitterTrackBar.Value * (TrainingTestBorder * 0.9);
+        }
+      }
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      foreach (LegendItem legendItem in e.LegendItems) {
+        var series = chart.Series[legendItem.SeriesName];
+        if (series != null) {
+          bool seriesIsInvisible = series.Points.Count == 0;
+          foreach (LegendCell cell in legendItem.Cells)
+            cell.ForeColor = seriesIsInvisible ? Color.Gray : Color.Black;
+        }
+      }
+    }
+
+    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 ToggleSeries(Series series) {
+      if (series.Points.Count == 0)
+        FillSeriesWithDataPoints(series);
+      else
+        series.Points.Clear();
+    }
+
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        if (result.Series != null) ToggleSeries(result.Series);
+      }
+    }
+
+    private void chart_AnnotationPositionChanging(object sender, AnnotationPositionChangingEventArgs e) {
+      int classIndex = (int)e.Annotation.Tag;
+      double[] thresholds = Content.Model.Thresholds.ToArray();
+      thresholds[classIndex] = e.NewLocationY;
+      Array.Sort(thresholds);
+      Content.Model.SetThresholdsAndClassValues(thresholds, Content.Model.ClassValues);
+    }
+
+    private void UpdateCursorInterval() {
+      Series series = chart.Series[0];
+      double[] xValues = (from point in series.Points
+                          where !point.IsEmpty
+                          select point.XValue)
+                    .DefaultIfEmpty(1.0)
+                    .ToArray();
+      double[] yValues = (from point in series.Points
+                          where !point.IsEmpty
+                          select point.YValues[0])
+                    .DefaultIfEmpty(1.0)
+                    .ToArray();
+
+      double xRange = xValues.Max() - xValues.Min();
+      double yRange = yValues.Max() - yValues.Min();
+      if (xRange.IsAlmost(0.0)) xRange = 1.0;
+      if (yRange.IsAlmost(0.0)) yRange = 1.0;
+      double xDigits = (int)Math.Log10(xRange) - 3;
+      double yDigits = (int)Math.Log10(yRange) - 3;
+      double xZoomInterval = Math.Pow(10, xDigits);
+      double yZoomInterval = Math.Pow(10, yDigits);
+      this.chart.ChartAreas[0].CursorX.Interval = xZoomInterval;
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.Designer.cs	(revision 16097)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClusteringSolutionEstimatedClusterView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // EstimatedValuesView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EstimatedValuesView";
+      this.Size = new System.Drawing.Size(310, 285);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionEstimatedClusterView.cs	(revision 16097)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Estimated Clusters")]
+  [Content(typeof(IClusteringSolution))]
+  public partial class ClusteringSolutionEstimatedClusterView : DataAnalysisSolutionEvaluationView {
+    private const string CLUSTER_NAMES = "Cluster";
+
+    public new IClusteringSolution Content {
+      get { return (IClusteringSolution)base.Content; }
+      set {
+        base.Content = value;
+      }
+    }
+
+    private StringConvertibleMatrixView matrixView;
+
+    public ClusteringSolutionEstimatedClusterView()
+      : base() {
+      InitializeComponent();
+      matrixView = new StringConvertibleMatrixView();
+      matrixView.ShowRowsAndColumnsTextBox = false;
+      matrixView.ShowStatisticalInformation = false;
+      matrixView.Dock = DockStyle.Fill;
+      this.Controls.Add(matrixView);
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateClusterValues();
+    }
+
+    private void UpdateClusterValues() {
+      if (InvokeRequired) Invoke((Action)UpdateClusterValues);
+      else {
+        DoubleMatrix matrix = null;
+        if (Content != null) {
+          int[] clusters = Content.Model.GetClusterValues(Content.ProblemData.Dataset, Enumerable.Range(0, Content.ProblemData.Dataset.Rows)).ToArray();
+          var dataset = Content.ProblemData.Dataset;
+          int columns = Content.ProblemData.AllowedInputVariables.Count() + 1;          
+
+          double[,] values = new double[dataset.Rows, columns];
+          for (int row = 0; row < dataset.Rows; row++) {
+            values[row, 0] = clusters[row];
+
+            int column = 1;
+            foreach (var columnName in Content.ProblemData.AllowedInputVariables) {
+              values[row, column] = dataset.GetDoubleValue(columnName, row);
+              column++;
+            }
+          }
+
+          matrix = new DoubleMatrix(values);
+          var columnNames = Content.ProblemData.AllowedInputVariables.ToList();
+          columnNames.Insert(0, CLUSTER_NAMES);
+          matrix.ColumnNames = columnNames;
+        }
+        matrixView.Content = matrix;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.Designer.cs	(revision 16097)
@@ -0,0 +1,116 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClusteringSolutionVisualizationView {
+    /// <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() {
+      this.splitContainer = new System.Windows.Forms.SplitContainer();
+      this.rangeComboBox = new System.Windows.Forms.ComboBox();
+      this.rangeLabel = new System.Windows.Forms.Label();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      this.splitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.splitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.splitContainer.IsSplitterFixed = true;
+      this.splitContainer.Location = new System.Drawing.Point(0, 0);
+      this.splitContainer.Name = "splitContainer";
+      this.splitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.rangeComboBox);
+      this.splitContainer.Panel1.Controls.Add(this.rangeLabel);
+      this.splitContainer.Size = new System.Drawing.Size(438, 198);
+      this.splitContainer.SplitterDistance = 27;
+      this.splitContainer.TabIndex = 1;
+      // 
+      // rangeComboBox
+      // 
+      this.rangeComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.rangeComboBox.FormattingEnabled = true;
+      this.rangeComboBox.Items.AddRange(new object[] {
+            "Training samples",
+            "Test samples",
+            "All samples"});
+      this.rangeComboBox.Location = new System.Drawing.Point(56, 3);
+      this.rangeComboBox.Name = "rangeComboBox";
+      this.rangeComboBox.Size = new System.Drawing.Size(146, 21);
+      this.rangeComboBox.TabIndex = 1;
+      this.rangeComboBox.SelectedIndexChanged += new System.EventHandler(this.rangeComboBox_SelectedIndexChanged);
+      // 
+      // rangeLabel
+      // 
+      this.rangeLabel.AutoSize = true;
+      this.rangeLabel.Location = new System.Drawing.Point(3, 6);
+      this.rangeLabel.Name = "rangeLabel";
+      this.rangeLabel.Size = new System.Drawing.Size(47, 13);
+      this.rangeLabel.TabIndex = 0;
+      this.rangeLabel.Text = "Samples";
+      // 
+      // ClusteringSolutionVisualizationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.splitContainer);
+      this.Name = "ClusteringSolutionVisualizationView";
+      this.Size = new System.Drawing.Size(438, 198);
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.SplitContainer splitContainer;
+    private System.Windows.Forms.ComboBox rangeComboBox;
+    private System.Windows.Forms.Label rangeLabel;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Clustering/ClusteringSolutionVisualizationView.cs	(revision 16097)
@@ -0,0 +1,133 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Cluster Visualization")]
+  [Content(typeof(IClusteringSolution), IsDefaultView = false)]
+  public partial class ClusteringSolutionVisualizationView : DataAnalysisSolutionEvaluationView {
+    private ViewHost viewHost = new ViewHost();
+    private ScatterPlot scatterPlot = new ScatterPlot();
+
+    public new IClusteringSolution Content {
+      get { return (IClusteringSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ClusteringSolutionVisualizationView() {
+      InitializeComponent();
+      viewHost.Dock = DockStyle.Fill;
+      splitContainer.Panel2.Controls.Add(viewHost);
+      rangeComboBox.SelectedIndex = 0;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        viewHost.Content = null;
+        scatterPlot.Rows.Clear();
+      } else {
+        UpdateScatterPlot();
+        viewHost.Content = scatterPlot;
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      rangeComboBox.Enabled = Content != null;
+    }
+
+    private void UpdateScatterPlot() {
+      scatterPlot.Rows.Clear();
+
+      IEnumerable<int> range = null;
+      if (rangeComboBox.SelectedIndex == 0) range = Content.ProblemData.TrainingIndices;
+      else if (rangeComboBox.SelectedIndex == 1) range = Content.ProblemData.TestIndices;
+      else range = Enumerable.Range(0, Content.ProblemData.Dataset.Rows);
+
+      IDictionary<int, Tuple<double, string>> classes = Content.Model.GetClusterValues(Content.ProblemData.Dataset, Enumerable.Range(0, Content.ProblemData.Dataset.Rows))
+          .Select((v, i) => new { Row = i, Cluster = (double)v })
+          .ToDictionary(x => x.Row, y => Tuple.Create(y.Cluster, "Cluster " + y.Cluster));
+
+      var rows = classes.Values.Select(x => x.Item2).Distinct().ToDictionary(c => c, c => new ScatterPlotDataRow(c, string.Empty, Enumerable.Empty<Point2D<double>>()));
+
+      var reduced = PCAReduce(Content.ProblemData.Dataset, range, Content.ProblemData.AllowedInputVariables, Content.Model);
+
+      int idx = 0;
+      foreach (var r in range) {
+        rows[classes[r].Item2].Points.Add(new Point2D<double>(reduced[idx, 0], reduced[idx, 1]));
+        idx++;
+      }
+
+      scatterPlot.Rows.AddRange(rows.Values);
+    }
+
+    private static double[,] PCAReduce(Dataset dataset, IEnumerable<int> rows, IEnumerable<string> variables, IDataAnalysisModel model) {
+      var clusteringModel = model as IClusteringModel;
+      if (clusteringModel == null) return new double[0, 0];
+
+      var instances = rows.ToArray();
+      var attributes = variables.ToArray();
+      var data = new double[instances.Length, attributes.Length + 1];
+
+      for (int j = 0; j < attributes.Length; j++) {
+        int i = 0;
+        var values = dataset.GetDoubleValues(attributes[j], instances);
+        foreach (var v in values) {
+          data[i++, j] = v;
+        }
+      }
+      int info;
+      double[] variances;
+      var matrix = new double[0, 0];
+      alglib.pcabuildbasis(data, instances.Length, attributes.Length, out info, out variances, out matrix);
+
+      var result = new double[instances.Length, 2];
+      int r = 0;
+      foreach (var inst in instances) {
+        int i = 0;
+        foreach (var attrib in attributes) {
+          double val = dataset.GetDoubleValue(attrib, inst);
+          for (int j = 0; j < result.GetLength(1); j++)
+            result[r, j] += val * matrix[i, j];
+          i++;
+        }
+        r++;
+      }
+
+      return result;
+    }
+
+    #region Event Handlers
+    private void rangeComboBox_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (Content != null) UpdateScatterPlot();
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.Designer.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DataAnalysisSolutionEvaluationView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DataAnalysisSolutionEvaluationView.cs	(revision 16097)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using HeuristicLab.Core.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class DataAnalysisSolutionEvaluationView : ItemView, IDataAnalysisSolutionEvaluationView {
+    public DataAnalysisSolutionEvaluationView() {
+      InitializeComponent();
+    }
+
+    public new IDataAnalysisSolution Content {
+      get { return (IDataAnalysisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public virtual Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Graph; }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.Designer.cs	(revision 16097)
@@ -0,0 +1,69 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class DoubleLimitView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // Item1Label
+      // 
+      this.Item1Label.Size = new System.Drawing.Size(39, 13);
+      this.Item1Label.Text = "Lower:";
+      // 
+      // Item2Label
+      // 
+      this.Item2Label.Size = new System.Drawing.Size(39, 13);
+      this.Item2Label.Text = "Upper:";
+      // 
+      // DoubleLimitView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Name = "DoubleLimitView";
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/DoubleLimitView.cs	(revision 16097)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("DoubleLimit View")]
+  [Content(typeof(DoubleLimit), true)]
+  public partial class DoubleLimitView : StringConvertibleValueTupleView {
+
+    public new DoubleLimit Content {
+      get { return (DoubleLimit)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public DoubleLimitView() {
+      InitializeComponent();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,245 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class AbstractFeatureCorrelationView {
+    /// <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() {
+      this.components = new System.ComponentModel.Container();
+      System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AbstractFeatureCorrelationView));
+      this.HeatMapProgressBar = new System.Windows.Forms.ProgressBar();
+      this.PartitionComboBox = new System.Windows.Forms.ComboBox();
+      this.CorrelationCalcLabel = new System.Windows.Forms.Label();
+      this.CorrelationCalcComboBox = new System.Windows.Forms.ComboBox();
+      this.PartitionLabel = new System.Windows.Forms.Label();
+      this.minimumLabel = new System.Windows.Forms.Label();
+      this.maximumLabel = new System.Windows.Forms.Label();
+      this.PictureBox = new System.Windows.Forms.PictureBox();
+      this.SplitContainer = new System.Windows.Forms.SplitContainer();
+      this.CalculatingPanel = new System.Windows.Forms.Panel();
+      this.CalculatingLabel = new System.Windows.Forms.Label();
+      this.dataView = new HeuristicLab.Problems.DataAnalysis.Views.EnhancedStringConvertibleMatrixView();
+      ((System.ComponentModel.ISupportInitialize)(this.PictureBox)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.SplitContainer)).BeginInit();
+      this.SplitContainer.Panel1.SuspendLayout();
+      this.SplitContainer.Panel2.SuspendLayout();
+      this.SplitContainer.SuspendLayout();
+      this.CalculatingPanel.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // HeatMapProgressBar
+      // 
+      this.HeatMapProgressBar.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
+      this.HeatMapProgressBar.Location = new System.Drawing.Point(25, 46);
+      this.HeatMapProgressBar.Name = "HeatMapProgressBar";
+      this.HeatMapProgressBar.RightToLeft = System.Windows.Forms.RightToLeft.No;
+      this.HeatMapProgressBar.Size = new System.Drawing.Size(154, 21);
+      this.HeatMapProgressBar.TabIndex = 9;
+      // 
+      // PartitionComboBox
+      // 
+      this.PartitionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.PartitionComboBox.FormattingEnabled = true;
+      this.PartitionComboBox.Location = new System.Drawing.Point(333, 3);
+      this.PartitionComboBox.Name = "PartitionComboBox";
+      this.PartitionComboBox.Size = new System.Drawing.Size(142, 21);
+      this.PartitionComboBox.TabIndex = 8;
+      this.PartitionComboBox.SelectionChangeCommitted += new System.EventHandler(this.PartitionComboBox_SelectedChangeCommitted);
+      // 
+      // CorrelationCalcLabel
+      // 
+      this.CorrelationCalcLabel.AutoSize = true;
+      this.CorrelationCalcLabel.Location = new System.Drawing.Point(0, 6);
+      this.CorrelationCalcLabel.Name = "CorrelationCalcLabel";
+      this.CorrelationCalcLabel.Size = new System.Drawing.Size(104, 13);
+      this.CorrelationCalcLabel.TabIndex = 7;
+      this.CorrelationCalcLabel.Text = "Correlation Measure:";
+      // 
+      // CorrelationCalcComboBox
+      // 
+      this.CorrelationCalcComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.CorrelationCalcComboBox.FormattingEnabled = true;
+      this.CorrelationCalcComboBox.Location = new System.Drawing.Point(110, 3);
+      this.CorrelationCalcComboBox.Name = "CorrelationCalcComboBox";
+      this.CorrelationCalcComboBox.Size = new System.Drawing.Size(163, 21);
+      this.CorrelationCalcComboBox.TabIndex = 6;
+      this.CorrelationCalcComboBox.SelectionChangeCommitted += new System.EventHandler(this.CorrelationMeasureComboBox_SelectedChangeCommitted);
+      // 
+      // PartitionLabel
+      // 
+      this.PartitionLabel.AutoSize = true;
+      this.PartitionLabel.Location = new System.Drawing.Point(279, 6);
+      this.PartitionLabel.Name = "PartitionLabel";
+      this.PartitionLabel.Size = new System.Drawing.Size(48, 13);
+      this.PartitionLabel.TabIndex = 10;
+      this.PartitionLabel.Text = "Partition:";
+      // 
+      // minimumLabel
+      // 
+      this.minimumLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+      this.minimumLabel.BackColor = System.Drawing.Color.Transparent;
+      this.minimumLabel.Location = new System.Drawing.Point(487, 314);
+      this.minimumLabel.Name = "minimumLabel";
+      this.minimumLabel.Size = new System.Drawing.Size(73, 19);
+      this.minimumLabel.TabIndex = 13;
+      this.minimumLabel.Text = "0.0";
+      this.minimumLabel.TextAlign = System.Drawing.ContentAlignment.TopCenter;
+      // 
+      // maximumLabel
+      // 
+      this.maximumLabel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+      this.maximumLabel.BackColor = System.Drawing.Color.Transparent;
+      this.maximumLabel.Location = new System.Drawing.Point(487, 2);
+      this.maximumLabel.Name = "maximumLabel";
+      this.maximumLabel.Size = new System.Drawing.Size(73, 25);
+      this.maximumLabel.TabIndex = 12;
+      this.maximumLabel.Text = "1.0";
+      this.maximumLabel.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
+      // 
+      // PictureBox
+      // 
+      this.PictureBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.PictureBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
+      this.PictureBox.Image = ((System.Drawing.Image)(resources.GetObject("PictureBox.Image")));
+      this.PictureBox.Location = new System.Drawing.Point(507, 30);
+      this.PictureBox.Name = "PictureBox";
+      this.PictureBox.Size = new System.Drawing.Size(35, 281);
+      this.PictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
+      this.PictureBox.TabIndex = 15;
+      this.PictureBox.TabStop = false;
+      // 
+      // SplitContainer
+      // 
+      this.SplitContainer.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+            | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.SplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
+      this.SplitContainer.IsSplitterFixed = true;
+      this.SplitContainer.Location = new System.Drawing.Point(3, 3);
+      this.SplitContainer.Name = "SplitContainer";
+      this.SplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
+      // 
+      // SplitContainer.Panel1
+      // 
+      this.SplitContainer.Panel1.Controls.Add(this.CorrelationCalcLabel);
+      this.SplitContainer.Panel1.Controls.Add(this.CorrelationCalcComboBox);
+      this.SplitContainer.Panel1.Controls.Add(this.PartitionComboBox);
+      this.SplitContainer.Panel1.Controls.Add(this.PartitionLabel);
+      // 
+      // SplitContainer.Panel2
+      // 
+      this.SplitContainer.Panel2.Controls.Add(this.CalculatingPanel);
+      this.SplitContainer.Panel2.Controls.Add(this.dataView);
+      this.SplitContainer.Size = new System.Drawing.Size(475, 330);
+      this.SplitContainer.SplitterDistance = 25;
+      this.SplitContainer.TabIndex = 16;
+      // 
+      // CalculatingPanel
+      // 
+      this.CalculatingPanel.Anchor = System.Windows.Forms.AnchorStyles.None;
+      this.CalculatingPanel.Controls.Add(this.CalculatingLabel);
+      this.CalculatingPanel.Controls.Add(this.HeatMapProgressBar);
+      this.CalculatingPanel.Location = new System.Drawing.Point(138, 95);
+      this.CalculatingPanel.Name = "CalculatingPanel";
+      this.CalculatingPanel.Size = new System.Drawing.Size(200, 81);
+      this.CalculatingPanel.TabIndex = 10;
+      // 
+      // CalculatingLabel
+      // 
+      this.CalculatingLabel.AutoSize = true;
+      this.CalculatingLabel.Location = new System.Drawing.Point(42, 19);
+      this.CalculatingLabel.Name = "CalculatingLabel";
+      this.CalculatingLabel.Size = new System.Drawing.Size(120, 13);
+      this.CalculatingLabel.TabIndex = 10;
+      this.CalculatingLabel.Text = "Calculating correlation...";
+      // 
+      // DataGridView
+      // 
+      this.dataView.Dock = System.Windows.Forms.DockStyle.Fill;
+      this.dataView.Location = new System.Drawing.Point(0, 0);
+      this.dataView.Name = "DataView";
+      this.dataView.ReadOnly = true;
+      this.dataView.Size = new System.Drawing.Size(475, 301);
+      this.dataView.TabIndex = 0;
+      // 
+      // AbstractFeatureCorrelationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.SplitContainer);
+      this.Controls.Add(this.minimumLabel);
+      this.Controls.Add(this.PictureBox);
+      this.Controls.Add(this.maximumLabel);
+      this.Name = "AbstractFeatureCorrelationView";
+      this.Size = new System.Drawing.Size(569, 336);
+      ((System.ComponentModel.ISupportInitialize)(this.PictureBox)).EndInit();
+      this.SplitContainer.Panel1.ResumeLayout(false);
+      this.SplitContainer.Panel1.PerformLayout();
+      this.SplitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.SplitContainer)).EndInit();
+      this.SplitContainer.ResumeLayout(false);
+      this.CalculatingPanel.ResumeLayout(false);
+      this.CalculatingPanel.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.ProgressBar HeatMapProgressBar;
+    protected System.Windows.Forms.ComboBox PartitionComboBox;
+    protected System.Windows.Forms.Label CorrelationCalcLabel;
+    protected System.Windows.Forms.ComboBox CorrelationCalcComboBox;
+    protected System.Windows.Forms.Label PartitionLabel;
+    protected System.Windows.Forms.Label minimumLabel;
+    protected System.Windows.Forms.Label maximumLabel;
+    protected System.Windows.Forms.PictureBox PictureBox;
+    protected System.Windows.Forms.SplitContainer SplitContainer;
+    protected System.Windows.Forms.Panel CalculatingPanel;
+    protected System.Windows.Forms.Label CalculatingLabel;
+    protected HeuristicLab.Problems.DataAnalysis.Views.EnhancedStringConvertibleMatrixView dataView;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,122 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.ComponentModel;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Feature Correlation View")]
+  [Content(typeof(DataAnalysisProblemData), false)]
+  public abstract partial class AbstractFeatureCorrelationView : AsynchronousContentView {
+    protected FeatureCorrelationCalculator fcc;
+    protected DoubleMatrix currentCorrelation;
+
+    public new DataAnalysisProblemData Content {
+      get { return (DataAnalysisProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected AbstractFeatureCorrelationView() {
+      InitializeComponent();
+      fcc = new FeatureCorrelationCalculator();
+      var calculators = ApplicationManager.Manager.GetInstances<IDependencyCalculator>();
+      var calcList = calculators.OrderBy(c => c.Name).Select(c => new { Name = c.Name, Calculator = c }).ToList();
+      CorrelationCalcComboBox.ValueMember = "Calculator";
+      CorrelationCalcComboBox.DisplayMember = "Name";
+      CorrelationCalcComboBox.DataSource = calcList;
+      CorrelationCalcComboBox.SelectedItem = calcList.First(c => c.Calculator.GetType().Equals(typeof(PearsonsRDependenceCalculator)));
+      PartitionComboBox.DataSource = FeatureCorrelationPartitions.Partitions;
+      PartitionComboBox.SelectedItem = FeatureCorrelationPartitions.TRAININGSAMPLES;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      fcc.ProgressCalculation += new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
+      fcc.CorrelationCalculationFinished += new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
+    }
+
+    protected override void DeregisterContentEvents() {
+      fcc.CorrelationCalculationFinished += new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished);
+      fcc.ProgressCalculation += new FeatureCorrelationCalculator.ProgressCalculationHandler(Content_ProgressCalculation);
+      base.DeregisterContentEvents();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      fcc.TryCancelCalculation();
+      if (Content != null) {
+        fcc.ProblemData = Content;
+        CalculateCorrelation();
+      } else {
+        dataView.Maximum = 0;
+        dataView.Minimum = 0;
+        dataView.Content = null;
+        dataView.ResetVisibility();
+      }
+    }
+
+    protected virtual bool[] SetInitialVariableVisibility() {
+      bool[] initialVisibility = new bool[Content.Dataset.DoubleVariables.Count()];
+      int i = 0;
+      foreach (var variable in Content.Dataset.DoubleVariables) {
+        initialVisibility[i] = Content.AllowedInputVariables.Contains(variable);
+        i++;
+      }
+      return initialVisibility;
+    }
+
+    protected void CorrelationMeasureComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
+      CalculateCorrelation();
+    }
+    protected void PartitionComboBox_SelectedChangeCommitted(object sender, System.EventArgs e) {
+      CalculateCorrelation();
+    }
+
+    protected abstract void CalculateCorrelation();
+    protected abstract void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e);
+
+    protected void UpdateDataView() {
+      IDependencyCalculator calc = (IDependencyCalculator)CorrelationCalcComboBox.SelectedValue;
+      maximumLabel.Text = calc.Maximum.ToString();
+      minimumLabel.Text = calc.Minimum.ToString();
+
+      currentCorrelation.SortableView = true;
+      dataView.Maximum = calc.Maximum;
+      dataView.Minimum = calc.Minimum;
+      dataView.Content = currentCorrelation;
+      dataView.Enabled = true;
+    }
+
+    protected void Content_ProgressCalculation(object sender, ProgressChangedEventArgs e) {
+      if (!CalculatingPanel.Visible && e.ProgressPercentage != HeatMapProgressBar.Maximum) {
+        CalculatingPanel.Show();
+      } else if (e.ProgressPercentage == HeatMapProgressBar.Maximum) {
+        CalculatingPanel.Hide();
+      }
+      HeatMapProgressBar.Value = e.ProgressPercentage;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.resx
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.resx	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/AbstractFeatureCorrelationView.resx	(revision 16097)
@@ -0,0 +1,1025 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+  <data name="PictureBox.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+    <value>
+        Qk0S0gAAAAAAADYAAAAoAAAAMQAAAGsBAAABABgAAAAAAAAAAADEDgAAxA4AAAAAAAAAAAAA/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe/wAe
+        /wAe/wAe/wAe/wAe/wAe/wAe/wAeAP8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8A
+        G/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8A
+        G/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AG/8AGwD/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/ABj/
+        ABj/ABj/ABj/ABj/ABj/ABgA/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV
+        /wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV
+        /wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAV/wAVAP8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8AEv8A
+        Ev8AEv8AEv8AEv8AEgD/AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//
+        AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//
+        AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA//AA8A/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM/wAM
+        /wAM/wAM/wAMAP8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8A
+        Cf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8A
+        Cf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACf8ACQD/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/AAb/
+        AAb/AAYA/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAGAP8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        AwD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMAAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAAD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQAA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwAAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAAD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgAA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUAAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAAD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwAA/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4AAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAAA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycAAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8qAP8q
+        AAD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/
+        LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/
+        LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQD/LQAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA
+        /zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA
+        /zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAA/zAAAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8z
+        AP8zAP8zAP8zAP8zAP8zAP8zAP8zAP8zAAD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/
+        NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/
+        NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgD/NgAA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA/zkA
+        /zkA/zkA/zkA/zkA/zkA/zkA/zkAAP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88
+        AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88
+        AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AP88AAD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/PwD/
+        PwD/PwD/PwD/PwD/PwD/PwAA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA
+        /0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA
+        /0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IA/0IAAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9FAP9F
+        AP9FAP9FAP9FAP9FAAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/
+        SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/
+        SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAD/SAAA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA/0sA
+        /0sA/0sA/0sAAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAAD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgAA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EAAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AAD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwAA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oAAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAAA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MAAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAAD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQAA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wAAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAAD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgAA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UAAP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94
+        AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94
+        AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AP94AAD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/ewD/
+        ewD/ewAA/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A
+        /34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34A
+        /34A/34A/34A/34A/34A/34A/34A/34A/34A/34A/34AAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+BAP+B
+        AAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/
+        hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/
+        hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAD/hAAA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA
+        /4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA
+        /4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cA/4cAAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+K
+        AP+KAP+KAP+KAP+KAP+KAP+KAP+KAP+KAAD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/
+        jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/
+        jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQD/jQAA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA/5AA
+        /5AA/5AA/5AA/5AA/5AA/5AA/5AAAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+T
+        AP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+T
+        AP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAP+TAAD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/lgD/
+        lgD/lgD/lgD/lgD/lgD/lgAA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA
+        /5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA
+        /5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kA/5kAAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAAA/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58AAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAAD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQAA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gAAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AAD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgAA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EAAP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AAD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twAA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oAAP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAAA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MAAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/GAP/G
+        AP/GAP/GAP/GAP/GAAD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/
+        yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/
+        yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQD/yQAA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA/8wA
+        /8wA/8wA/8wAAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/P
+        AP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/P
+        AP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAP/PAAD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/0gD/
+        0gD/0gAA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA
+        /9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA
+        /9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UA/9UAAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/YAP/Y
+        AAD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/
+        2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/
+        2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wD/2wAA/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A
+        /94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A
+        /94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94A/94AAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/h
+        AP/hAP/hAP/hAP/hAP/hAP/hAP/hAP/hAAD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/
+        5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/
+        5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AD/5AAA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA/+cA
+        /+cA/+cA/+cA/+cA/+cA/+cA/+cAAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAAD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gAA/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0AAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAAD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wAA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YAAP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AAD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AAA//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8AAPz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        AAD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wAA9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8AAPP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/AADw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wAA7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8AAOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AADn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn/wDn
+        /wDn/wDn/wDn/wDn/wDn/wAA5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A
+        5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A
+        5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8A5P8AAOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/AOH/
+        AOH/AOH/AOH/AOH/AADe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe
+        /wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe
+        /wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wDe/wAA2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A2/8A
+        2/8A2/8A2/8AANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/
+        ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/
+        ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/ANj/AADV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV/wDV
+        /wDV/wAA0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A
+        0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A
+        0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8A0v8AAM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//AM//
+        AADM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM
+        /wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM
+        /wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wDM/wAAyf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8A
+        yf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8A
+        yf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8Ayf8AAMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/
+        AMb/AMb/AMb/AMb/AMb/AMb/AMb/AMb/AADG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wAAw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8AAMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AAC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wAAuv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8AALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/AAC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wAAsf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8AAK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AACr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wAAqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AAKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AACi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wAAn/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8AAJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AACZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ
+        /wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ
+        /wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wCZ/wAAlv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8Alv8A
+        lv8Alv8Alv8Alv8Alv8Alv8Alv8AAJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/
+        AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/
+        AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AJP/AACQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ/wCQ
+        /wCQ/wCQ/wCQ/wCQ/wCQ/wAAjf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8A
+        jf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8A
+        jf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8Ajf8AAIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/AIr/
+        AIr/AIr/AIr/AIr/AACH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH
+        /wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH
+        /wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wCH/wAAhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8AhP8A
+        hP8AhP8AhP8AAIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/
+        AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/
+        AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AIH/AAB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+/wB+
+        /wB+/wAAe/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8A
+        e/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8A
+        e/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8Ae/8AAHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/AHj/
+        AAB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wAAdf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8AAHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AABv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wAAbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AAGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AABm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wAAY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AAGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AABd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wAAWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AAFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AABU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wAAUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AAE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AABL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL
+        /wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL
+        /wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wBL/wAASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8A
+        SP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8A
+        SP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8ASP8AAEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/
+        AEX/AEX/AEX/AEX/AEX/AEX/AEX/AEX/AABC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC
+        /wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC
+        /wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wBC/wAAP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8AP/8A
+        P/8AP/8AP/8AP/8AP/8AP/8AP/8AADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/
+        ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/
+        ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/ADz/AAA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5/wA5
+        /wA5/wA5/wA5/wA5/wA5/wAANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8A
+        Nv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8A
+        Nv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8ANv8AADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/ADP/
+        ADP/ADP/ADP/ADP/AAAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw
+        /wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw
+        /wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAw/wAALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8ALf8A
+        Lf8ALf8ALf8AACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/
+        ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/
+        ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/ACr/AAAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAAJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        AAAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAAHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/AAAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAAFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/AAAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8AAAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAAA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AAAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/
+        AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAD/AAAA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA/wMA
+        /wMA/wMAAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8G
+        AP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAP8GAAD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/CQD/
+        CQAA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA
+        /wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwA/wwAAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8P
+        AP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAP8PAAD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/
+        EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgD/EgAA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA
+        /xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUA/xUAAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8YAP8Y
+        AP8YAP8YAP8YAP8YAP8YAP8YAP8YAAD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/
+        GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwD/GwAA/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A/x4A
+        /x4A/x4A/x4A/x4A/x4A/x4AAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8h
+        AP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAP8hAAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/JAD/
+        JAD/JAD/JAD/JAD/JAAA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA
+        /ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycA/ycAAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8nAP8n
+        AP8nAP8nAP8nAAD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/
+        KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/
+        KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgD/KgAA/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A/y0A
+        /y0A/y0AAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8w
+        AP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8w
+        AP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAP8wAAD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/MwD/
+        MwAA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA
+        /zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA
+        /zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYA/zYAAP85AP85AP85AP85AP85AP85AP85AP85AP85AP85
+        AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85
+        AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AP85AAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/
+        PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAD/PAAA/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A
+        /z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A
+        /z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8A/z8AAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9CAP9C
+        AP9CAP9CAP9CAP9CAP9CAP9CAP9CAAD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/
+        RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/
+        RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQD/RQAA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA/0gA
+        /0gA/0gA/0gA/0gA/0gA/0gAAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9L
+        AP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAP9LAAD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/TgD/
+        TgD/TgD/TgD/TgD/TgAA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA
+        /1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EA/1EAAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9UAP9U
+        AP9UAP9UAP9UAAD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/
+        VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwD/VwAA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA/1oA
+        /1oA/1oAAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9d
+        AP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAP9dAAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/YAD/
+        YAAA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA
+        /2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MA/2MAAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9m
+        AP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAP9mAAD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/
+        aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQD/aQAA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA
+        /2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wA/2wAAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9vAP9v
+        AP9vAP9vAP9vAP9vAP9vAP9vAP9vAAD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/
+        cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgD/cgAA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA/3UA
+        /3UA/3UA/3UA/3UA/3UA/3UAAP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91
+        AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91
+        AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AP91AAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/eAD/
+        eAD/eAD/eAD/eAD/eAAA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA
+        /3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA
+        /3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sA/3sAAP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+AP9+
+        AP9+AP9+AP9+AAD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/
+        gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/
+        gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQD/gQAA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA/4QA
+        /4QA/4QAAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+H
+        AP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+H
+        AP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAP+HAAD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/igD/
+        igAA/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A
+        /40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A/40A
+        /40A/40A/40A/40A/40A/40A/40A/40A/40A/40AAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+Q
+        AP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+Q
+        AP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAP+QAAD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/
+        kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwD/kwAA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA
+        /5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA
+        /5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YA/5YAAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+Z
+        AP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAP+ZAAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/
+        nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAD/nAAA/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A/58A
+        /58A/58A/58A/58A/58A/58AAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+i
+        AP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAP+iAAD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/pQD/
+        pQD/pQD/pQD/pQD/pQAA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA
+        /6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gA/6gAAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+rAP+r
+        AP+rAP+rAP+rAAD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/
+        rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgD/rgAA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA/7EA
+        /7EA/7EAAP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0
+        AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AP+0AAD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/twD/
+        twAA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA
+        /7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oA/7oAAP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9
+        AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AP+9AAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/
+        wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAD/wAAA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA
+        /8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MA/8MAAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/DAP/D
+        AP/DAP/DAP/DAP/DAP/DAP/DAP/DAAD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/
+        xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/
+        xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgD/xgAA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA/8kA
+        /8kA/8kA/8kA/8kA/8kA/8kAAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/M
+        AP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/M
+        AP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAP/MAAD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/zwD/
+        zwD/zwD/zwD/zwD/zwAA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA
+        /9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA
+        /9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IA/9IAAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/VAP/V
+        AP/VAP/VAP/VAAD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/
+        2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/
+        2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AD/2AAA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA/9sA
+        /9sA/9sAAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/e
+        AP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/e
+        AP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAP/eAAD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/4QD/
+        4QAA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA
+        /+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA
+        /+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QA/+QAAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/n
+        AP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAP/nAAD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/
+        6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gD/6gAA/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A
+        /+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0A/+0AAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/w
+        AP/wAP/wAP/wAP/wAP/wAP/wAP/wAAD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/
+        8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wD/8wAA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA//YA
+        //YA//YA//YA//YA//YA//YAAP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5
+        AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AP/5AAD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD/
+        /AD//AD//AD//AD//AAA//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A
+        //8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8A//8AAPz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/APz/
+        APz/APz/APz/AAD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5
+        /wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wD5/wAA9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A9v8A
+        9v8A9v8AAPP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/
+        APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/APP/AADw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw/wDw
+        /wAA7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A
+        7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8A7f8AAOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/
+        AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AOr/AADq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq
+        /wDq/wDq/wDq/wDq/wDq/wDq/wDq/wDq/wAA5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A
+        5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A
+        5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8A5/8AAOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/AOT/
+        AOT/AOT/AOT/AOT/AOT/AOT/AOT/AADh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh
+        /wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh
+        /wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wDh/wAA3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A3v8A
+        3v8A3v8A3v8A3v8A3v8A3v8AANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/
+        ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/
+        ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/ANv/AADY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY/wDY
+        /wDY/wDY/wDY/wDY/wAA1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A
+        1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A
+        1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8A1f8AANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/ANL/
+        ANL/ANL/ANL/AADP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP
+        /wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP
+        /wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wDP/wAAzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8AzP8A
+        zP8AzP8AAMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/
+        AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/
+        AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AMn/AADG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG/wDG
+        /wAAw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8A
+        w/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8Aw/8AAMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/
+        AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AMD/AAC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9
+        /wC9/wC9/wC9/wC9/wC9/wC9/wC9/wC9/wAAuv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8A
+        uv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8Auv8AALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/ALf/
+        ALf/ALf/ALf/ALf/ALf/ALf/ALf/AAC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0
+        /wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wC0/wAAsf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8Asf8A
+        sf8Asf8Asf8Asf8Asf8Asf8AAK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/
+        AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AK7/AACr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr/wCr
+        /wCr/wCr/wCr/wCr/wAAqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8A
+        qP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AqP8AAKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/AKX/
+        AKX/AKX/AKX/AACi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi
+        /wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wCi/wAAn/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8An/8A
+        n/8An/8AAJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/
+        AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AJz/AACc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc/wCc
+        /wAAmf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8A
+        mf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8A
+        mf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8Amf8AAJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/
+        AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/
+        AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AJb/AACT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT
+        /wCT/wCT/wCT/wCT/wCT/wCT/wCT/wCT/wAAkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8A
+        kP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8A
+        kP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AkP8AAI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/AI3/
+        AI3/AI3/AI3/AI3/AI3/AI3/AI3/AACK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK
+        /wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK
+        /wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wCK/wAAh/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8Ah/8A
+        h/8Ah/8Ah/8Ah/8Ah/8Ah/8AAIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/
+        AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/
+        AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AIT/AACB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB/wCB
+        /wCB/wCB/wCB/wCB/wAAfv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8A
+        fv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8A
+        fv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8Afv8AAHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/AHv/
+        AHv/AHv/AHv/AAB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4
+        /wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wB4/wAAdf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8Adf8A
+        df8Adf8AAHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/
+        AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AHL/AABv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv/wBv
+        /wAAbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8A
+        bP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AbP8AAGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/
+        AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AGn/AABm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm
+        /wBm/wBm/wBm/wBm/wBm/wBm/wBm/wBm/wAAY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8A
+        Y/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AY/8AAGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/AGD/
+        AGD/AGD/AGD/AGD/AGD/AGD/AGD/AABd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd
+        /wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wBd/wAAWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8AWv8A
+        Wv8AWv8AWv8AWv8AWv8AWv8AAFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/
+        AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AFf/AABU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU/wBU
+        /wBU/wBU/wBU/wBU/wAAUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8A
+        Uf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AUf8AAE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/AE7/
+        AE7/AE7/AE7/AABO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO
+        /wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO
+        /wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wBO/wAAS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8AS/8A
+        S/8AS/8AAEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/
+        AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/
+        AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AEj/AABF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF/wBF
+        /wAAQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8A
+        Qv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8A
+        Qv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AQv8AAD//AD//AD//AD//AD//AD//AD//AD//AD//AD//
+        AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//
+        AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AD//AAA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8
+        /wA8/wA8/wA8/wA8/wA8/wA8/wA8/wA8/wAAOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8A
+        Of8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8A
+        Of8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AOf8AADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/ADb/
+        ADb/ADb/ADb/ADb/ADb/ADb/ADb/AAAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz
+        /wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz
+        /wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAz/wAAMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8AMP8A
+        MP8AMP8AMP8AMP8AMP8AMP8AAC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/
+        AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/
+        AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AC3/AAAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq/wAq
+        /wAq/wAq/wAq/wAq/wAAJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8A
+        J/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AJ/8AACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/ACT/
+        ACT/ACT/ACT/AAAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh
+        /wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAh/wAAHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8AHv8A
+        Hv8AHv8AABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/
+        ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/ABv/AAAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY/wAY
+        /wAAFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8A
+        Ff8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AFf8AABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/
+        ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/ABL/AAAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP
+        /wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAP/wAADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8A
+        DP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8ADP8AAAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAn/
+        AAn/AAn/AAn/AAn/AAn/AAn/AAn/AAAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG
+        /wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAG/wAAA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8AA/8A
+        A/8AA/8AA/8AA/8AA/8AA/8A
+</value>
+  </data>
+  <metadata name="contextMenu.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+</root>
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.Designer.cs	(revision 16097)
@@ -0,0 +1,72 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class EnhancedStringConvertibleMatrixView {
+    /// <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() {
+      this.ShowHideRows = new System.Windows.Forms.ToolStripMenuItem();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // rowsTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.rowsTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.rowsTextBox, 2);
+      //
+      // dataGridView
+      //
+      this.dataGridView.CellPainting += new System.Windows.Forms.DataGridViewCellPaintingEventHandler(dataGridView_CellPainting);
+      // 
+      // contextMenu
+      // 
+      this.contextMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+            this.ShowHideRows});
+      // 
+      // ShowHideRows
+      // 
+      this.ShowHideRows.Name = "ShowHideRows";
+      this.ShowHideRows.Size = new System.Drawing.Size(190, 22);
+      this.ShowHideRows.Text = "Show / Hide Rows";
+      this.ShowHideRows.Click += new System.EventHandler(this.ShowHideRows_Click);
+      // 
+      // ColoredStringConvertibleMatrixView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "ColoredStringConvertibleMatrixView";
+      this.ShowRowsAndColumnsTextBox = false;
+      this.ShowStatisticalInformation = false;
+      this.Controls.SetChildIndex(this.statisticsTextBox, 0);
+      this.Controls.SetChildIndex(this.rowsLabel, 0);
+      this.Controls.SetChildIndex(this.columnsLabel, 0);
+      this.Controls.SetChildIndex(this.rowsTextBox, 0);
+      this.Controls.SetChildIndex(this.columnsTextBox, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+    #endregion
+
+    protected System.Windows.Forms.ToolStripMenuItem ShowHideRows;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/EnhancedStringConvertibleMatrixView.cs	(revision 16097)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Data.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public partial class EnhancedStringConvertibleMatrixView : StringConvertibleMatrixView {
+
+    protected IEnumerable<bool> columnVisibility, rowVisibility;
+
+    // sets the visibility of its columns for the next time it is updated
+    public IEnumerable<bool> ColumnVisibility { set { columnVisibility = value; } }
+    // sets the visibility of its rows for the next time it is updated
+    public IEnumerable<bool> RowVisibility { set { rowVisibility = value; } }
+
+    public double Maximum { get; set; }
+    public double Minimum { get; set; }
+
+    public new DoubleMatrix Content {
+      get { return (DoubleMatrix)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public EnhancedStringConvertibleMatrixView() {
+      InitializeComponent();
+    }
+
+    public void ResetVisibility() {
+      columnVisibility = null;
+      rowVisibility = null;
+    }
+
+    protected override void UpdateColumnHeaders() {
+      base.UpdateColumnHeaders();
+      if (columnVisibility != null && Content != null && columnVisibility.Count() == dataGridView.ColumnCount) {
+        int i = 0;
+        foreach (var visibility in columnVisibility) {
+          dataGridView.Columns[i].Visible = visibility;
+          i++;
+        }
+      }
+    }
+    protected override void UpdateRowHeaders() {
+      base.UpdateRowHeaders();
+      if (rowVisibility != null && Content != null && rowVisibility.Count() == dataGridView.RowCount) {
+        int i = 0;
+        foreach (var visibility in rowVisibility) {
+          dataGridView.Rows[i].Visible = visibility;
+          i++;
+        }
+      }
+    }
+
+    protected virtual void ShowHideRows_Click(object sender, EventArgs e) {
+      var dialog = new StringConvertibleMatrixRowVisibilityDialog(this.dataGridView.Rows.Cast<DataGridViewRow>());
+      dialog.ShowDialog();
+      rowVisibility = dialog.Visibility;
+    }
+
+    protected override void ShowHideColumns_Click(object sender, EventArgs e) {
+      var dialog = new StringConvertibleMatrixColumnVisibilityDialog(this.dataGridView.Columns.Cast<DataGridViewColumn>());
+      dialog.ShowDialog();
+      columnVisibility = dialog.Visibility;
+    }
+
+    protected void dataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e) {
+      if (Content == null) return;
+      if (e.RowIndex < 0) return;
+      if (e.ColumnIndex < 0) return;
+      if (e.State.HasFlag(DataGridViewElementStates.Selected)) return;
+      if (!e.PaintParts.HasFlag(DataGridViewPaintParts.Background)) return;
+
+      int rowIndex = virtualRowIndices[e.RowIndex];
+      Color backColor = GetDataPointColor(Content[rowIndex, e.ColumnIndex], Minimum, Maximum);
+      using (Brush backColorBrush = new SolidBrush(backColor)) {
+        e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
+      }
+      e.PaintContent(e.CellBounds);
+      e.Handled = true;
+    }
+
+    protected virtual Color GetDataPointColor(double value, double min, double max) {
+      if (double.IsNaN(value)) {
+        return Color.DarkGray;
+      }
+      IList<Color> colors = ColorGradient.Colors;
+      int index = (int)((colors.Count - 1) * (value - min) / (max - min));
+      if (index >= colors.Count) index = colors.Count - 1;
+      if (index < 0) index = 0;
+      return colors[index];
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCache.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCache.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCache.cs	(revision 16097)
@@ -0,0 +1,58 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  internal class FeatureCorrelationCache : Object {
+    private Dictionary<FeatureCorrelationEnums.CorrelationCalculators, Dictionary<FeatureCorrelationEnums.Partitions, double[,]>> correlationsCache;
+
+    public FeatureCorrelationCache()
+      : base() {
+      InitializeCaches();
+    }
+
+    private void InitializeCaches() {
+      correlationsCache = new Dictionary<FeatureCorrelationEnums.CorrelationCalculators, Dictionary<FeatureCorrelationEnums.Partitions, double[,]>>();
+      foreach (var calc in FeatureCorrelationEnums.EnumToList<FeatureCorrelationEnums.CorrelationCalculators>()) {
+        correlationsCache.Add(calc, new Dictionary<FeatureCorrelationEnums.Partitions, double[,]>());
+      }
+    }
+
+    public void Reset() {
+      InitializeCaches();
+    }
+
+    public double[,] GetCorrelation(FeatureCorrelationEnums.CorrelationCalculators calc, FeatureCorrelationEnums.Partitions partition) {
+      double[,] corr;
+      correlationsCache[calc].TryGetValue(partition, out corr);
+      return corr;
+    }
+
+    public void SetCorrelation(FeatureCorrelationEnums.CorrelationCalculators calc, FeatureCorrelationEnums.Partitions partition, double[,] correlation) {
+      correlationsCache[calc][partition] = correlation;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationCalculator.cs	(revision 16097)
@@ -0,0 +1,271 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  public class FeatureCorrelationCalculator : Object {
+
+    private BackgroundWorker bw;
+    private BackgroundWorkerInfo bwInfo;
+
+    private IDataAnalysisProblemData problemData;
+    public IDataAnalysisProblemData ProblemData {
+      set {
+        if (bw != null) {
+          bw.CancelAsync();
+        }
+        problemData = value;
+      }
+    }
+
+    public FeatureCorrelationCalculator()
+      : base() { }
+
+    public FeatureCorrelationCalculator(IDataAnalysisProblemData problemData)
+      : base() {
+      this.problemData = problemData;
+    }
+
+    public void CalculateElements(IDependencyCalculator calc, string partition) {
+      CalculateElements(problemData.Dataset, calc, partition);
+    }
+
+    // returns true if any calculation takes place
+    public bool CalculateTimeframeElements(IDependencyCalculator calc, string partition, string variable, int frames, double[,] correlation = null) {
+      if (correlation == null || correlation.GetLength(1) <= frames) {
+        CalculateElements(problemData.Dataset, calc, partition, variable, frames, correlation);
+        return true;
+      } else {
+        return false;
+      }
+    }
+
+    public void TryCancelCalculation() {
+      if (bw != null && bw.IsBusy) {
+        bwInfo = null;
+        bw.CancelAsync();
+      }
+    }
+
+    private double[,] GetElementsOfCorrelation(double[,] corr, int frames) {
+      double[,] elements = new double[corr.GetLength(0), frames + 1];
+      for (int i = 0; i < corr.GetLength(0); i++) {
+        for (int j = 0; j <= frames; j++) {
+          elements[i, j] = corr[i, j];
+        }
+      }
+      return elements;
+    }
+
+    private void CalculateElements(Dataset dataset, IDependencyCalculator calc, string partition, string variable = null, int frames = 0, double[,] alreadyCalculated = null) {
+      bwInfo = new BackgroundWorkerInfo { Dataset = dataset, Calculator = calc, Partition = partition, Variable = variable, Frames = frames, AlreadyCalculated = alreadyCalculated };
+      if (bw == null) {
+        bw = new BackgroundWorker();
+        bw.WorkerReportsProgress = true;
+        bw.WorkerSupportsCancellation = true;
+        bw.DoWork += new DoWorkEventHandler(BwDoWork);
+        bw.ProgressChanged += new ProgressChangedEventHandler(BwProgressChanged);
+        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BwRunWorkerCompleted);
+      }
+      if (bw.IsBusy) {
+        bw.CancelAsync();
+      } else {
+        bw.RunWorkerAsync(bwInfo);
+      }
+    }
+
+    #region backgroundworker
+    private void BwDoWork(object sender, DoWorkEventArgs e) {
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
+      if (bwInfo.Variable == null) {
+        BwCalculateCorrelation(sender, e);
+      } else {
+        BwCalculateTimeframeCorrelation(sender, e);
+      }
+    }
+
+    private void BwCalculateCorrelation(object sender, DoWorkEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
+      Dataset dataset = bwInfo.Dataset;
+      string partition = bwInfo.Partition;
+      IDependencyCalculator calc = bwInfo.Calculator;
+
+      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
+      OnlineCalculatorError error = OnlineCalculatorError.None;
+      int length = doubleVariableNames.Count;
+      double[,] elements = new double[length, length];
+      double calculations = (Math.Pow(length, 2) + length) / 2;
+
+      worker.ReportProgress(0);
+
+      for (int i = 0; i < length; i++) {
+        for (int j = 0; j < i + 1; j++) {
+          if (worker.CancellationPending) {
+            worker.ReportProgress(100);
+            e.Cancel = true;
+            return;
+          }
+          IEnumerable<double> var1 = GetRelevantValues(problemData, partition, doubleVariableNames[i]);
+          IEnumerable<double> var2 = GetRelevantValues(problemData, partition, doubleVariableNames[j]);
+
+          elements[i, j] = calc.Calculate(var1, var2, out error);
+
+          if (!error.Equals(OnlineCalculatorError.None)) {
+            elements[i, j] = double.NaN;
+          }
+          elements[j, i] = elements[i, j];
+          worker.ReportProgress((int)Math.Round((((Math.Pow(i, 2) + i) / 2 + j + 1.0) / calculations) * 100));
+        }
+      }
+      e.Result = elements;
+      worker.ReportProgress(100);
+    }
+
+    private void BwCalculateTimeframeCorrelation(object sender, DoWorkEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+
+      BackgroundWorkerInfo bwInfo = (BackgroundWorkerInfo)e.Argument;
+      Dataset dataset = bwInfo.Dataset;
+      string partition = bwInfo.Partition;
+      IDependencyCalculator calc = bwInfo.Calculator;
+      string variable = bwInfo.Variable;
+      int frames = bwInfo.Frames;
+      double[,] alreadyCalculated = bwInfo.AlreadyCalculated;
+
+      IList<string> doubleVariableNames = dataset.DoubleVariables.ToList();
+      OnlineCalculatorError error = OnlineCalculatorError.None;
+      int length = doubleVariableNames.Count;
+      double[,] elements = new double[length, frames + 1];
+      double calculations = (frames + 1) * length;
+
+      worker.ReportProgress(0);
+
+      int start = 0;
+      if (alreadyCalculated != null) {
+        for (int i = 0; i < alreadyCalculated.GetLength(0); i++) {
+          Array.Copy(alreadyCalculated, i * alreadyCalculated.GetLength(1), elements, i * elements.GetLength(1), alreadyCalculated.GetLength(1));
+        }
+        start = alreadyCalculated.GetLength(1);
+      }
+
+      for (int i = 0; i < length; i++) {
+        for (int j = start; j <= frames; j++) {
+          if (worker.CancellationPending) {
+            worker.ReportProgress(100);
+            e.Cancel = true;
+            return;
+          }
+
+          IEnumerable<double> var1 = GetRelevantValues(problemData, partition, variable);
+          IEnumerable<double> var2 = GetRelevantValues(problemData, partition, doubleVariableNames[i]);
+
+          var valuesInFrame = var1.Take(j);
+          var help = var1.Skip(j).ToList();
+          help.AddRange(valuesInFrame);
+          var1 = help;
+
+          elements[i, j] = calc.Calculate(var1, var2, out error);
+
+          if (!error.Equals(OnlineCalculatorError.None)) {
+            elements[i, j] = double.NaN;
+          }
+          worker.ReportProgress((int)((100.0 / calculations) * (i * (frames + 1) + j + 1)));
+        }
+      }
+      e.Result = elements;
+      worker.ReportProgress(100);
+    }
+
+    private IEnumerable<double> GetRelevantValues(IDataAnalysisProblemData problemData, string partition, string variable) {
+      IEnumerable<double> var = problemData.Dataset.GetDoubleValues(variable);
+      if (partition.Equals(FeatureCorrelationPartitions.TRAININGSAMPLES)) {
+        var = var.Skip(problemData.TrainingPartition.Start).Take(problemData.TrainingPartition.End - problemData.TrainingPartition.Start);
+      } else if (partition.Equals(FeatureCorrelationPartitions.TESTSAMPLES)) {
+        var = var.Skip(problemData.TestPartition.Start).Take(problemData.TestPartition.End - problemData.TestPartition.Start);
+      }
+      return var;
+    }
+
+    private void BwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+      if (!e.Cancelled && !worker.CancellationPending) {
+        if (!(e.Error == null)) {
+          ErrorHandling.ShowErrorDialog(e.Error);
+        } else {
+          OnCorrelationCalculationFinished((double[,])e.Result, bwInfo.Calculator, bwInfo.Partition, bwInfo.Variable);
+        }
+      } else if (bwInfo != null) {
+        bw.RunWorkerAsync(bwInfo);
+      }
+    }
+    #endregion
+
+    #region events
+    public class CorrelationCalculationFinishedArgs : EventArgs {
+      public double[,] Correlation { get; private set; }
+      public IDependencyCalculator Calculcator { get; private set; }
+      public string Partition { get; private set; }
+      public string Variable { get; private set; }
+
+      public CorrelationCalculationFinishedArgs(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
+        this.Correlation = correlation;
+        this.Calculcator = calculator;
+        this.Partition = partition;
+        this.Variable = variable;
+      }
+    }
+
+    public delegate void CorrelationCalculationFinishedHandler(object sender, CorrelationCalculationFinishedArgs e);
+    public event CorrelationCalculationFinishedHandler CorrelationCalculationFinished;
+    protected virtual void OnCorrelationCalculationFinished(double[,] correlation, IDependencyCalculator calculator, string partition, string variable = null) {
+      var handler = CorrelationCalculationFinished;
+      if (handler != null)
+        handler(this, new CorrelationCalculationFinishedArgs(correlation, calculator, partition, variable));
+    }
+
+    public delegate void ProgressCalculationHandler(object sender, ProgressChangedEventArgs e);
+    public event ProgressCalculationHandler ProgressCalculation;
+    protected void BwProgressChanged(object sender, ProgressChangedEventArgs e) {
+      BackgroundWorker worker = sender as BackgroundWorker;
+      if (ProgressCalculation != null) {
+        ProgressCalculation(sender, e);
+      }
+    }
+    #endregion
+
+    private class BackgroundWorkerInfo {
+      public Dataset Dataset { get; set; }
+      public IDependencyCalculator Calculator { get; set; }
+      public string Partition { get; set; }
+      public string Variable { get; set; }
+      public int Frames { get; set; }
+      public double[,] AlreadyCalculated { get; set; }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationEnums.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationEnums.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationEnums.cs	(revision 16097)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
+using HeuristicLab.Data;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  // see http://blog.spontaneouspublicity.com/associating-strings-with-enums-in-c
+  [NonDiscoverableType]
+  public class FeatureCorrelationEnums {
+    public enum Partitions {
+      [Description("All Samples")]
+      AllSamples,
+      [Description("Training Samples")]
+      TrainingSamples,
+      [Description("Test Samples")]
+      TestSamples
+    }
+
+    public enum CorrelationCalculators {
+      [Description("Pearsons R")]
+      PearsonsR,
+      [Description("Pearsons R Squared")]
+      PearsonsRSquared,
+      [Description("Hoeffdings Dependence")]
+      HoeffdingsDependence,
+      [Description("Spearmans Rank")]
+      SpearmansRank
+    }
+
+    public static readonly Dictionary<CorrelationCalculators, DoubleRange> calculatorInterval = new Dictionary<CorrelationCalculators, DoubleRange>(){ 
+      { CorrelationCalculators.PearsonsR, new DoubleRange(1.0, -1.0)},
+      { CorrelationCalculators.SpearmansRank, new DoubleRange(1.0, -1.0)},
+      { CorrelationCalculators.HoeffdingsDependence, new DoubleRange(1.0, -0.5)},
+      { CorrelationCalculators.PearsonsRSquared, new DoubleRange(1.0, 0.0)}
+    };
+
+    public static string GetEnumDescription(object value) {
+      FieldInfo fi = value.GetType().GetField(value.ToString());
+
+      DescriptionAttribute[] attributes =
+          (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
+
+      if (attributes != null && attributes.Length > 0)
+        return attributes[0].Description;
+      else
+        return value.ToString();
+    }
+
+    public static IEnumerable<T> EnumToList<T>() {
+      Type enumType = typeof(T);
+
+      // Can't use generic type constraints on value types,
+      // so have to do check like this
+      if (enumType.BaseType != typeof(Enum)) {
+        throw new ArgumentException("T must be of type System.Enum");
+      }
+
+      Array enumValArray = Enum.GetValues(enumType);
+      return Enum.GetValues(enumType).Cast<int>().Select(x => (T)Enum.Parse(enumType, x.ToString())).ToList();
+    }
+
+    public static T GetEnumOfDescription<T>(string desc) {
+      Type enumType = typeof(T);
+
+      if (enumType.BaseType != typeof(Enum))
+        throw new ArgumentException("T must be of type System.Enum");
+
+      Array enumValArray = Enum.GetValues(enumType);
+      foreach (int val in enumValArray) {
+
+        T e = (T)Enum.Parse(enumType, val.ToString());
+        if (GetEnumDescription(e).Equals(desc)) {
+          return (T)e;
+        }
+      }
+      throw new ArgumentException("Description is not in the given type T");
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationHelpers.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationHelpers.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationHelpers.cs	(revision 16097)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  public class FeatureCorrelationPartitions {
+    public const string ALLSAMPLES = "All Samples";
+    public const string TRAININGSAMPLES = "Training Samples";
+    public const string TESTSAMPLES = "Test Samples";
+
+    public static readonly IList<string> Partitions = new List<string>() { ALLSAMPLES, TRAININGSAMPLES, TESTSAMPLES };
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationTimeframeCache.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationTimeframeCache.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationTimeframeCache.cs	(revision 16097)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [NonDiscoverableType]
+  internal class FeatureCorrelationTimeframeCache : Object {
+    private Dictionary<FeatureCorrelationEnums.CorrelationCalculators, Dictionary<FeatureCorrelationEnums.Partitions, Dictionary<string, double[,]>>> timeFrameCorrelationsCache;
+
+    public FeatureCorrelationTimeframeCache()
+      : base() {
+      InitializeCaches();
+    }
+
+    private void InitializeCaches() {
+      timeFrameCorrelationsCache = new Dictionary<FeatureCorrelationEnums.CorrelationCalculators, Dictionary<FeatureCorrelationEnums.Partitions, Dictionary<string, double[,]>>>();
+      foreach (var calc in FeatureCorrelationEnums.EnumToList<FeatureCorrelationEnums.CorrelationCalculators>()) {
+        timeFrameCorrelationsCache.Add(calc, new Dictionary<FeatureCorrelationEnums.Partitions, Dictionary<string, double[,]>>());
+        foreach (var part in FeatureCorrelationEnums.EnumToList<FeatureCorrelationEnums.Partitions>()) {
+          timeFrameCorrelationsCache[calc].Add(part, new Dictionary<string, double[,]>());
+        }
+      }
+    }
+
+    public void Reset() {
+      InitializeCaches();
+    }
+
+    public double[,] GetTimeframeCorrelation(FeatureCorrelationEnums.CorrelationCalculators calc, FeatureCorrelationEnums.Partitions partition, string variable) {
+      double[,] corr;
+      timeFrameCorrelationsCache[calc][partition].TryGetValue(variable, out corr);
+      return corr;
+    }
+
+    public void SetTimeframeCorrelation(FeatureCorrelationEnums.CorrelationCalculators calc, FeatureCorrelationEnums.Partitions partition, string variable, double[,] correlation) {
+      timeFrameCorrelationsCache[calc][partition][variable] = correlation;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,60 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class FeatureCorrelationView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // FeatureCorrelationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "FeatureCorrelationView";
+      this.Size = new System.Drawing.Size(569, 336);
+      this.ResumeLayout(false);
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/FeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,114 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Feature Correlation View")]
+  [Content(typeof(DataAnalysisProblemData), false)]
+  public partial class FeatureCorrelationView : AbstractFeatureCorrelationView {
+
+    private FeatureCorrelationCache correlationCache;
+
+    public FeatureCorrelationView()
+      : base() {
+      InitializeComponent();
+      correlationCache = new FeatureCorrelationCache();
+    }
+
+    protected override void OnContentChanged() {
+      if (Content != null) {
+        dataView.RowVisibility = SetInitialVariableVisibility();
+        dataView.ColumnVisibility = SetInitialVariableVisibility();
+      }
+      correlationCache.Reset();
+      base.OnContentChanged();
+    }
+
+    protected override void CalculateCorrelation() {
+      if (CorrelationCalcComboBox.SelectedItem != null && PartitionComboBox.SelectedItem != null) {
+        IDependencyCalculator calc = (IDependencyCalculator)CorrelationCalcComboBox.SelectedValue;
+        string partition = (string)PartitionComboBox.SelectedValue;
+        dataView.Enabled = false;
+        double[,] corr = correlationCache.GetCorrelation(calc, partition);
+        if (corr == null) {
+          fcc.CalculateElements(calc, partition);
+        } else {
+          fcc.TryCancelCalculation();
+          SetNewCorrelation(corr);
+          UpdateDataView();
+        }
+      }
+    }
+
+    private void SetNewCorrelation(double[,] elements) {
+      currentCorrelation = new DoubleMatrix(elements,
+                                            Content.Dataset.DoubleVariables,
+                                            Content.Dataset.DoubleVariables);
+    }
+
+    protected override void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
+      if (InvokeRequired) {
+        Invoke(new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished), sender, e);
+      } else {
+        correlationCache.SetCorrelation(e.Calculcator, e.Partition, e.Correlation);
+        SetNewCorrelation(e.Correlation);
+        UpdateDataView();
+      }
+    }
+
+    [NonDiscoverableType]
+    private class FeatureCorrelationCache : Object {
+      private Dictionary<Tuple<IDependencyCalculator, string>, double[,]> correlationsCache;
+
+      public FeatureCorrelationCache()
+        : base() {
+        InitializeCaches();
+      }
+
+      private void InitializeCaches() {
+        correlationsCache = new Dictionary<Tuple<IDependencyCalculator, string>, double[,]>();
+      }
+
+      public void Reset() {
+        InitializeCaches();
+      }
+
+      public double[,] GetCorrelation(IDependencyCalculator calc, string partition) {
+        double[,] corr;
+        var key = new Tuple<IDependencyCalculator, string>(calc, partition);
+        correlationsCache.TryGetValue(key, out corr);
+        return corr;
+      }
+
+      public void SetCorrelation(IDependencyCalculator calc, string partition, double[,] correlation) {
+        var key = new Tuple<IDependencyCalculator, string>(calc, partition);
+        correlationsCache[key] = correlation;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,149 @@
+﻿#region License Information
+
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeframeFeatureCorrelationView {
+    /// <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() {
+      this.VariableSelectionLabel = new System.Windows.Forms.Label();
+      this.VariableSelectionComboBox = new System.Windows.Forms.ComboBox();
+      this.TimeFrameLabel = new System.Windows.Forms.Label();
+      this.TimeframeTextbox = new System.Windows.Forms.TextBox();
+      ((System.ComponentModel.ISupportInitialize)(this.PictureBox)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.SplitContainer)).BeginInit();
+      this.SplitContainer.Panel1.SuspendLayout();
+      this.SplitContainer.Panel2.SuspendLayout();
+      this.SplitContainer.SuspendLayout();
+      this.CalculatingPanel.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // PartitionComboBox
+      // 
+      this.PartitionComboBox.Location = new System.Drawing.Point(344, 3);
+      this.PartitionComboBox.Size = new System.Drawing.Size(131, 21);
+      // 
+      // maximumLabel
+      // 
+      this.maximumLabel.Location = new System.Drawing.Point(487, 3);
+      // 
+      // PictureBox
+      // 
+      this.PictureBox.Location = new System.Drawing.Point(506, 31);
+      this.PictureBox.Size = new System.Drawing.Size(35, 280);
+      // 
+      // SplitContainer
+      // 
+      // 
+      // SplitContainer.Panel1
+      // 
+      this.SplitContainer.Panel1.Controls.Add(this.VariableSelectionComboBox);
+      this.SplitContainer.Panel1.Controls.Add(this.TimeframeTextbox);
+      this.SplitContainer.Panel1.Controls.Add(this.TimeFrameLabel);
+      this.SplitContainer.Panel1.Controls.Add(this.VariableSelectionLabel);
+      this.SplitContainer.SplitterDistance = 52;
+      // 
+      // CalculatingPanel
+      // 
+      this.CalculatingPanel.Location = new System.Drawing.Point(138, 82);
+      // 
+      // VariableSelectionLabel
+      // 
+      this.VariableSelectionLabel.AutoSize = true;
+      this.VariableSelectionLabel.Location = new System.Drawing.Point(0, 33);
+      this.VariableSelectionLabel.Name = "VariableSelectionLabel";
+      this.VariableSelectionLabel.Size = new System.Drawing.Size(81, 13);
+      this.VariableSelectionLabel.TabIndex = 16;
+      this.VariableSelectionLabel.Text = "Select Variable:";
+      // 
+      // VariableSelectionComboBox
+      // 
+      this.VariableSelectionComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.VariableSelectionComboBox.FormattingEnabled = true;
+      this.VariableSelectionComboBox.Location = new System.Drawing.Point(110, 30);
+      this.VariableSelectionComboBox.Name = "VariableSelectionComboBox";
+      this.VariableSelectionComboBox.Size = new System.Drawing.Size(163, 21);
+      this.VariableSelectionComboBox.TabIndex = 17;
+      this.VariableSelectionComboBox.SelectionChangeCommitted += new System.EventHandler(this.VariableSelectionComboBox_SelectedChangeCommitted);
+      // 
+      // TimeFrameLabel
+      // 
+      this.TimeFrameLabel.AutoSize = true;
+      this.TimeFrameLabel.Location = new System.Drawing.Point(279, 33);
+      this.TimeFrameLabel.Name = "TimeFrameLabel";
+      this.TimeFrameLabel.Size = new System.Drawing.Size(59, 13);
+      this.TimeFrameLabel.TabIndex = 18;
+      this.TimeFrameLabel.Text = "Timeframe:";
+      // 
+      // TimeframeComboBox
+      // 
+      this.TimeframeTextbox.Location = new System.Drawing.Point(344, 30);
+      this.TimeframeTextbox.Name = "TimeframeTextbox";
+      this.TimeframeTextbox.Size = new System.Drawing.Size(131, 21);
+      this.TimeframeTextbox.TabIndex = 19;
+      this.TimeframeTextbox.Text = "5";
+      this.TimeframeTextbox.KeyDown += new System.Windows.Forms.KeyEventHandler(TimeframeTextbox_KeyDown);
+      // 
+      // TimeframeFeatureCorrelationView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeframeFeatureCorrelationView";
+      ((System.ComponentModel.ISupportInitialize)(this.PictureBox)).EndInit();
+      this.SplitContainer.Panel1.ResumeLayout(false);
+      this.SplitContainer.Panel1.PerformLayout();
+      this.SplitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.SplitContainer)).EndInit();
+      this.SplitContainer.ResumeLayout(false);
+      this.CalculatingPanel.ResumeLayout(false);
+      this.CalculatingPanel.PerformLayout();
+      this.ResumeLayout(false);
+
+    }
+    #endregion
+
+    protected System.Windows.Forms.Label VariableSelectionLabel;
+    protected System.Windows.Forms.ComboBox VariableSelectionComboBox;
+    protected System.Windows.Forms.Label TimeFrameLabel;
+    protected System.Windows.Forms.TextBox TimeframeTextbox;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/FeatureCorrelation/TimeframeFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,151 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Timeframe Feature Correlation View")]
+  [Content(typeof(DataAnalysisProblemData), false)]
+  public partial class TimeframeFeatureCorrelationView : AbstractFeatureCorrelationView {
+
+    private FeatureCorrelationTimeframeCache correlationTimeframCache;
+
+    public TimeframeFeatureCorrelationView() {
+      InitializeComponent();
+      correlationTimeframCache = new FeatureCorrelationTimeframeCache();
+    }
+
+    protected override void OnContentChanged() {
+      correlationTimeframCache.Reset();
+      if (Content != null) {
+        dataView.RowVisibility = SetInitialVariableVisibility();
+        VariableSelectionComboBox.DataSource = Content.Dataset.DoubleVariables.ToList();
+      }
+      base.OnContentChanged();
+    }
+
+    protected void VariableSelectionComboBox_SelectedChangeCommitted(object sender, EventArgs e) {
+      CalculateCorrelation();
+    }
+    protected void TimeframeTextbox_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
+      if (e.KeyCode == Keys.Enter) {
+        CalculateCorrelation();
+      }
+    }
+
+    protected override void CalculateCorrelation() {
+      if (CorrelationCalcComboBox.SelectedItem != null && PartitionComboBox.SelectedItem != null
+        && VariableSelectionComboBox.SelectedItem != null && ValidateTimeframeTextbox()) {
+        string variable = (string)VariableSelectionComboBox.SelectedItem;
+        IDependencyCalculator calc = (IDependencyCalculator)CorrelationCalcComboBox.SelectedValue;
+        string partition = (string)PartitionComboBox.SelectedValue;
+        int frames;
+        int.TryParse(TimeframeTextbox.Text, out frames);
+        dataView.Enabled = false;
+        double[,] corr = correlationTimeframCache.GetTimeframeCorrelation(calc, partition, variable);
+        if (corr == null) {
+          fcc.CalculateTimeframeElements(calc, partition, variable, frames);
+        } else if (corr.GetLength(1) <= frames) {
+          fcc.CalculateTimeframeElements(calc, partition, variable, frames, corr);
+        } else {
+          fcc.TryCancelCalculation();
+          SetNewCorrelation(corr, calc, frames);
+          UpdateDataView();
+        }
+      }
+    }
+
+    protected bool ValidateTimeframeTextbox() {
+      int help;
+      if (!int.TryParse(TimeframeTextbox.Text, out help)) {
+        MessageBox.Show("Timeframe couldn't be parsed. Enter a valid integer value.", "Parse Error", MessageBoxButtons.OK);
+        return false;
+      } else {
+        if (help > 50) {
+          DialogResult dr = MessageBox.Show("The entered value is bigger than 50. Are you sure you want to calculate? " +
+                                            "The calculation could take some time.", "Huge Value Warning", MessageBoxButtons.YesNo);
+          return dr.Equals(DialogResult.Yes);
+        }
+      }
+      return true;
+    }
+
+    private void SetNewCorrelation(double[,] elements, IDependencyCalculator calc, int frames) {
+      double[,] neededValues = new double[elements.GetLength(0), frames + 1];
+      for (int i = 0; i < elements.GetLength(0); i++) {
+        Array.Copy(elements, i * elements.GetLength(1), neededValues, i * neededValues.GetLength(1), frames + 1);
+      }
+      SetNewCorrelation(neededValues);
+    }
+
+    private void SetNewCorrelation(double[,] elements) {
+      currentCorrelation = new DoubleMatrix(elements,
+                                            Enumerable.Range(0, elements.GetLength(1)).Select(x => x.ToString()),
+                                            Content.Dataset.DoubleVariables);
+    }
+
+    protected override void Content_CorrelationCalculationFinished(object sender, FeatureCorrelationCalculator.CorrelationCalculationFinishedArgs e) {
+      if (InvokeRequired) {
+        Invoke(new FeatureCorrelationCalculator.CorrelationCalculationFinishedHandler(Content_CorrelationCalculationFinished), sender, e);
+      } else {
+        correlationTimeframCache.SetTimeframeCorrelation(e.Calculcator, e.Partition, e.Variable, e.Correlation);
+        SetNewCorrelation(e.Correlation);
+        UpdateDataView();
+      }
+    }
+
+    [NonDiscoverableType]
+    private class FeatureCorrelationTimeframeCache : Object {
+      private Dictionary<Tuple<IDependencyCalculator, string, string>, double[,]> timeFrameCorrelationsCache;
+
+      public FeatureCorrelationTimeframeCache()
+        : base() {
+        InitializeCaches();
+      }
+
+      private void InitializeCaches() {
+        timeFrameCorrelationsCache = new Dictionary<Tuple<IDependencyCalculator, string, string>, double[,]>();
+      }
+
+      public void Reset() {
+        InitializeCaches();
+      }
+
+      public double[,] GetTimeframeCorrelation(IDependencyCalculator calc, string partition, string variable) {
+        double[,] corr;
+        var key = new Tuple<IDependencyCalculator, string, string>(calc, partition, variable);
+        timeFrameCorrelationsCache.TryGetValue(key, out corr);
+        return corr;
+      }
+
+      public void SetTimeframeCorrelation(IDependencyCalculator calc, string partition, string variable, double[,] correlation) {
+        var key = new Tuple<IDependencyCalculator, string, string>(calc, partition, variable);
+        timeFrameCorrelationsCache[key] = correlation;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/HeuristicLab.Problems.DataAnalysis.Views-3.4.csproj	(revision 16097)
@@ -0,0 +1,471 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3E9E8944-44FF-40BB-A622-3A4A7DD0F198}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis.Views</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis.Views-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.MainForm.WindowsForms-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.MainForm.WindowsForms-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimizer-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimizer-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters.Views-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters.Views-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Visualization.ChartControlsExtensions-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Visualization.ChartControlsExtensions-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Windows.Forms.DataVisualization" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Classification\ClassificationEnsembleSolutionEstimatedClassValuesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationEnsembleSolutionEstimatedClassValuesView.Designer.cs">
+      <DependentUpon>ClassificationEnsembleSolutionEstimatedClassValuesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationEnsembleSolutionModelView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationEnsembleSolutionModelView.Designer.cs">
+      <DependentUpon>ClassificationEnsembleSolutionModelView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationFeatureCorrelationView.Designer.cs">
+      <DependentUpon>ClassificationFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationTimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationTimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>ClassificationTimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationModelView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationModelView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationModelView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionVisualizationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionVisualizationView.Designer.cs">
+      <DependentUpon>ClusteringSolutionVisualizationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\AbstractFeatureCorrelationView.Designer.cs">
+      <DependentUpon>AbstractFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationEnsembleSolutionAccuracyToCoveredSamples.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationEnsembleSolutionAccuracyToCoveredSamples.Designer.cs">
+      <DependentUpon>ClassificationEnsembleSolutionAccuracyToCoveredSamples.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DataAnalysisSolutionEvaluationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DataAnalysisSolutionEvaluationView.Designer.cs">
+      <DependentUpon>DataAnalysisSolutionEvaluationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\EnhancedStringConvertibleMatrixView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\EnhancedStringConvertibleMatrixView.Designer.cs">
+      <DependentUpon>EnhancedStringConvertibleMatrixView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationCalculator.cs" />
+    <Compile Include="FeatureCorrelation\FeatureCorrelationHelpers.cs" />
+    <Compile Include="FeatureCorrelation\FeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\FeatureCorrelationView.Designer.cs">
+      <DependentUpon>FeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Plugin.cs" />
+    <Compile Include="ProblemDataView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="ProblemDataView.Designer.cs">
+      <DependentUpon>ProblemDataView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionFeatureCorrelationView.Designer.cs">
+      <DependentUpon>RegressionFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionTimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionTimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>RegressionTimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionModelView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionEnsembleSolutionModelView.Designer.cs">
+      <DependentUpon>RegressionEnsembleSolutionModelView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionErrorCharacteristicsCurveView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionErrorCharacteristicsCurveView.Designer.cs">
+      <DependentUpon>RegressionSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionEstimatedValuesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionEstimatedValuesView.Designer.cs">
+      <DependentUpon>RegressionSolutionEstimatedValuesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionLineChartView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionLineChartView.Designer.cs">
+      <DependentUpon>RegressionSolutionLineChartView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualHistogram.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionResidualHistogram.Designer.cs">
+      <DependentUpon>RegressionSolutionResidualHistogram.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionScatterPlotView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Regression\RegressionSolutionScatterPlotView.Designer.cs">
+      <DependentUpon>RegressionSolutionScatterPlotView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\ClassificationSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\ClassificationSolutionView.Designer.cs">
+      <DependentUpon>ClassificationSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationSolutionConfusionMatrixView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationSolutionConfusionMatrixView.Designer.cs">
+      <DependentUpon>ClassificationSolutionConfusionMatrixView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\ClassificationSolutionEstimatedClassValuesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\ClassificationSolutionEstimatedClassValuesView.Designer.cs">
+      <DependentUpon>ClassificationSolutionEstimatedClassValuesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationSolutionEstimatedClassValuesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationRocCurvesView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationRocCurvesView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationRocCurvesView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationSolutionThresholdView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Classification\DiscriminantFunctionClassificationSolutionThresholdView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationSolutionThresholdView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionEstimatedClusterView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Clustering\ClusteringSolutionEstimatedClusterView.Designer.cs">
+      <DependentUpon>ClusteringSolutionEstimatedClusterView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\ClusteringSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\ClusteringSolutionView.Designer.cs">
+      <DependentUpon>ClusteringSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\ClassificationEnsembleSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\ClassificationEnsembleSolutionView.Designer.cs">
+      <DependentUpon>ClassificationEnsembleSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\DiscriminantFunctionClassificationSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\DiscriminantFunctionClassificationSolutionView.Designer.cs">
+      <DependentUpon>DiscriminantFunctionClassificationSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\DataAnalysisSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\DataAnalysisSolutionView.Designer.cs">
+      <DependentUpon>DataAnalysisSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="DoubleLimitView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="DoubleLimitView.Designer.cs">
+      <DependentUpon>DoubleLimitView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Interfaces\IDataAnalysisSolutionEvaluationView.cs" />
+    <Compile Include="MenuItems\CreateEnsembleMenuItem.cs" />
+    <Compile Include="Solution Views\NamedDataAnalysisSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\NamedDataAnalysisSolutionView.Designer.cs">
+      <DependentUpon>NamedDataAnalysisSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\RegressionEnsembleSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\RegressionEnsembleSolutionView.Designer.cs">
+      <DependentUpon>RegressionEnsembleSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\RegressionSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\RegressionSolutionView.Designer.cs">
+      <DependentUpon>RegressionSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="FeatureCorrelation\TimeframeFeatureCorrelationView.Designer.cs">
+      <DependentUpon>TimeframeFeatureCorrelationView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="Solution Views\TimeSeriesPrognosisSolutionView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisSolutionView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisResultsView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisResultsView.cs</DependentUpon>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs">
+      <SubType>UserControl</SubType>
+    </Compile>
+    <Compile Include="TimeSeriesPrognosis\TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs">
+      <DependentUpon>TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs</DependentUpon>
+    </Compile>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj">
+      <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project>
+      <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="FeatureCorrelation\AbstractFeatureCorrelationView.resx">
+      <DependentUpon>AbstractFeatureCorrelationView.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IDataAnalysisSolutionEvaluationView.cs	(revision 16097)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using System.Drawing;
+using HeuristicLab.MainForm;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public interface IDataAnalysisSolutionEvaluationView :IContentView {
+    Image ViewImage { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Interfaces/IRegressionEnsembleSolutionEvaluationView.cs	(revision 16097)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  public interface IRegressionEnsembleSolutionEvaluationView : IDataAnalysisSolutionEvaluationView {
+    new IRegressionEnsembleSolution Content { get; set; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/MenuItems/CreateEnsembleMenuItem.cs	(revision 16097)
@@ -0,0 +1,108 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimizer;
+
+namespace HeuristicLab.Problems.DataAnalysis.MenuItems {
+  internal class CreateEnsembleMenuItem : HeuristicLab.MainForm.WindowsForms.MenuItem, IOptimizerUserInterfaceItemProvider {
+    public override string Name {
+      get { return "Create &Solution Ensembles"; }
+    }
+    public override IEnumerable<string> Structure {
+      get { return new string[] { "&Edit" }; }
+    }
+    public override int Position {
+      get { return 2500; }
+    }
+    public override string ToolTipText {
+      get { return "Create ensembles of data analysis solutions from the solutions in the current optimizer."; }
+    }
+
+    protected override void OnToolStripItemSet(EventArgs e) {
+      ToolStripItem.Enabled = false;
+    }
+    protected override void OnActiveViewChanged(object sender, EventArgs e) {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if ((activeView != null) && (activeView.Content != null) && (activeView.Content is IOptimizer) && !activeView.Locked) {
+        var optimizer = activeView.Content as IOptimizer;
+        ToolStripItem.Enabled = GetDataAnalysisResults(optimizer).Any();
+      } else {
+        ToolStripItem.Enabled = false;
+      }
+    }
+
+    public override void Execute() {
+      IContentView activeView = MainFormManager.MainForm.ActiveView as IContentView;
+      if ((activeView != null) && (activeView.Content != null) && (activeView.Content is IOptimizer) && !activeView.Locked) {
+        var optimizer = activeView.Content as IOptimizer;
+        var solutionGroups = from pair in GetDataAnalysisResults(optimizer)
+                             group pair.Value by pair.Key into g
+                             select g;
+        foreach (var group in solutionGroups) {
+          // check if all solutions in the group are either only regression or only classification solutions
+          if (group.All(s => s is IRegressionSolution)) {
+            // show all regression ensembles
+            // clone problemdata (N.B. this assumes all solutions are based on the same problem data!)
+            var problemData = (RegressionProblemData)group
+              .OfType<IRegressionSolution>()
+              .First()
+              .ProblemData.Clone();
+            var ensemble = new RegressionEnsembleSolution(problemData);
+            ensemble.Name = group.Key + " ensemble";
+            var nestedSolutions = group.OfType<RegressionEnsembleSolution>().SelectMany(e => e.RegressionSolutions);
+            var solutions = group.Where(s => !(s is RegressionEnsembleSolution)).OfType<IRegressionSolution>();
+            ensemble.AddRegressionSolutions(nestedSolutions.Concat(solutions));
+            MainFormManager.MainForm.ShowContent(ensemble);
+          } else if (group.All(s => s is IClassificationSolution)) {
+            // show all classification ensembles
+            var problemData = (ClassificationProblemData)group
+              .OfType<IClassificationSolution>()
+              .First()
+              .ProblemData.Clone();
+            var ensemble = new ClassificationEnsembleSolution(Enumerable.Empty<IClassificationModel>(), problemData);
+            ensemble.Name = group.Key + " ensemble";
+            var nestedSolutions = group.OfType<ClassificationEnsembleSolution>().SelectMany(e => e.ClassificationSolutions);
+            var solutions = group.Where(s => !(s is ClassificationEnsembleSolution)).OfType<IClassificationSolution>();
+            ensemble.AddClassificationSolutions(nestedSolutions.Concat(solutions));
+            MainFormManager.MainForm.ShowContent(ensemble);
+          }
+        }
+      }
+    }
+
+    private IEnumerable<KeyValuePair<string, IItem>> GetDataAnalysisResults(IOptimizer optimizer) {
+      var allResults = from r in optimizer.Runs
+                       select r.Results;
+      return from r in allResults
+             from result in r
+             let s = result.Value as IDataAnalysisSolution
+             where s != null
+             select result;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Plugin.cs.frame	(revision 16097)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [Plugin("HeuristicLab.Problems.DataAnalysis.Views", "Provides views for base classes for data analysis tasks.", "3.4.3.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.DataAnalysis.Views-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB", "3.6.0")]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Core.Views", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Data.Views", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm", "3.3")]
+  [PluginDependency("HeuristicLab.MainForm.WindowsForms", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Optimization.Views","3.3")]
+  [PluginDependency("HeuristicLab.Optimizer", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")]
+  public class HeuristicLabProblemsDataAnalysisViewsPlugin : PluginBase {
+  }
+}
+
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.Designer.cs	(revision 16097)
@@ -0,0 +1,74 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ProblemDataView {
+    /// <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() {
+      this.FeatureCorrelationButton = new System.Windows.Forms.Button();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // parameterCollectionView
+      // 
+      this.parameterCollectionView.AllowDrop = true;
+      this.parameterCollectionView.DragDrop += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragDrop);
+      this.parameterCollectionView.DragEnter += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragEnterOver);
+      this.parameterCollectionView.DragOver += new System.Windows.Forms.DragEventHandler(this.parameterCollectionView_DragEnterOver);
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // FeatureCorrelationButton
+      // 
+      this.FeatureCorrelationButton.Location = new System.Drawing.Point(184, 45);
+      this.FeatureCorrelationButton.Name = "FeatureCorrelationButton";
+      this.FeatureCorrelationButton.Size = new System.Drawing.Size(121, 24);
+      this.FeatureCorrelationButton.TabIndex = 4;
+      this.FeatureCorrelationButton.Text = "Feature Correlation";
+      this.FeatureCorrelationButton.UseVisualStyleBackColor = true;
+      this.FeatureCorrelationButton.Click += new System.EventHandler(this.FeatureCorrelationButton_Click);
+      // 
+      // ProblemDataView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Controls.Add(this.FeatureCorrelationButton);
+      this.Name = "ProblemDataView";
+      this.Controls.SetChildIndex(this.parameterCollectionView, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.FeatureCorrelationButton, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.Button FeatureCorrelationButton;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/ProblemDataView.cs	(revision 16097)
@@ -0,0 +1,103 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Problem Data View")]
+  [Content(typeof(DataAnalysisProblemData), true)]
+  public partial class ProblemDataView : ParameterizedNamedItemView {
+
+    public new DataAnalysisProblemData Content {
+      get { return (DataAnalysisProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public ProblemDataView() {
+      InitializeComponent();
+    }
+
+    protected void FeatureCorrelationButton_Click(object sender, System.EventArgs e) {
+      Type viewType = MainFormManager.GetViewTypes(this.Content.GetType(), true).FirstOrDefault(t => typeof(FeatureCorrelationView).IsAssignableFrom(t));
+      MainFormManager.MainForm.ShowContent(Content, viewType);
+    }
+
+    protected void parameterCollectionView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var stringValueList = (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IFixedValueParameter).Value as ICheckedItemList<StringValue>;
+        SetInputVariables(stringValueList);
+      }
+    }
+
+    private void SetInputVariables(ICheckedItemList<StringValue> stringValueList) {
+      var inputVariables = Content.InputVariables;
+      var stringValues = stringValueList.Select(x => x.Value);
+      var notContainedVariables = inputVariables.Where(x => !stringValues.Contains(x.Value));
+
+      if (notContainedVariables.Count() != 0) {
+        StringBuilder strBuilder = new StringBuilder();
+        foreach (var variable in notContainedVariables) {
+          strBuilder.Append(variable.Value + ", ");
+        }
+        strBuilder.Remove(strBuilder.Length - 2, 2);
+        MessageBox.Show(String.Format("There was an error while changing the input variables. The following input " +
+          "variables have not been contained {0}", strBuilder.ToString()), "Error while changing the input variables",
+          MessageBoxButtons.OK, MessageBoxIcon.Warning);
+      } else {
+        var checkedItems = stringValueList.CheckedItems.Select(x => x.Value.Value);
+        var setChecked = inputVariables.Where(x => checkedItems.Contains(x.Value));
+        foreach (var variable in inputVariables) {
+          if (setChecked.Contains(variable) && !inputVariables.ItemChecked(variable)) {
+            inputVariables.SetItemCheckedState(variable, true);
+          } else if (!setChecked.Contains(variable) && inputVariables.ItemChecked(variable)) {
+            inputVariables.SetItemCheckedState(variable, false);
+          }
+        }
+      }
+    }
+
+    protected void parameterCollectionView_DragEnterOver(object sender, DragEventArgs e) {
+      e.Effect = DragDropEffects.None;
+      if (ReadOnly)
+        return;
+      if (e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) == null)
+        return;
+
+      var parameter = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat) as IFixedValueParameter;
+      if (parameter == null)
+        return;
+
+      var stringValueList = parameter.Value as ICheckedItemList<StringValue>;
+      if (stringValueList == null)
+        return;
+
+      e.Effect = e.AllowedEffect;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Properties/AssemblyInfo.cs.frame	(revision 16097)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.DataAnalysis.Views")]
+[assembly: AssemblyDescription("Provides views for base classes for data analysis tasks.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("02BF0343-EAFB-445c-858C-E0038FAC0219")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.3.$WCREV$")]
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.Designer.cs	(revision 16097)
@@ -0,0 +1,59 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionEnsembleSolutionModelView {
+    /// <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() {
+      this.SuspendLayout();
+
+      // 
+      // RegressionSolutionEnsembleModelView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "RegressionEnsembleSolutionModelView";
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionEnsembleSolutionModelView.cs	(revision 16097)
@@ -0,0 +1,91 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Ensemble Solutions")]
+  [Content(typeof(RegressionEnsembleSolution), false)]
+  internal sealed partial class RegressionEnsembleSolutionModelView : DataAnalysisSolutionEvaluationView {
+    private ModelsView view;
+
+    public RegressionEnsembleSolutionModelView() {
+      InitializeComponent();
+      view = new ModelsView();
+      view.Dock = DockStyle.Fill;
+      Controls.Add(view);
+    }
+
+    public new RegressionEnsembleSolution Content {
+      get { return (RegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content != null) {
+        view.Locked = Content.ProblemData == RegressionEnsembleProblemData.EmptyProblemData;
+        view.Content = Content.RegressionSolutions;
+      } else
+        view.Content = null;
+    }
+
+    public override System.Drawing.Image ViewImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Properties; }
+    }
+
+    private class ModelsView : ItemCollectionView<IRegressionSolution> {
+      protected override void SetEnabledStateOfControls() {
+        base.SetEnabledStateOfControls();
+        addButton.Enabled = Content != null && !Content.IsReadOnly && !Locked;
+        removeButton.Enabled = Content != null && !Content.IsReadOnly && !Locked && itemsListView.SelectedItems.Count > 0;
+        itemsListView.Enabled = Content != null && !Locked;
+        detailsGroupBox.Enabled = Content != null && itemsListView.SelectedItems.Count == 1;
+      }
+
+      protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+        validDragOperation = false;
+        if (ReadOnly || Locked) return;
+        if (Content.IsReadOnly) return;
+
+        var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        validDragOperation = dropData.GetObjectGraphObjects().OfType<IRegressionSolution>().Any();
+      }
+      protected override void itemsListView_DragDrop(object sender, DragEventArgs e) {
+        if (e.Effect != DragDropEffects.None) {
+          var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+          var solutions = dropData.GetObjectGraphObjects().OfType<IRegressionSolution>();
+          if (e.Effect.HasFlag(DragDropEffects.Copy)) {
+            Cloner cloner = new Cloner();
+            solutions = solutions.Select(s => cloner.Clone(s));
+          }
+          foreach (var solution in solutions)
+            Content.Add(solution);
+        }
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionFeatureCorrelationView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Regression Feature Correlation View")]
+  [Content(typeof(RegressionProblemData), false)]
+  public partial class RegressionFeatureCorrelationView : FeatureCorrelationView {
+
+    public new RegressionProblemData Content {
+      get { return (RegressionProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVariableVisibility() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVariableVisibility();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 16097)
@@ -0,0 +1,93 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionErrorCharacteristicsCurveView {
+    /// <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() {
+      this.components = new System.ComponentModel.Container();
+      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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      this.label1 = new System.Windows.Forms.Label();
+      this.cmbSamples = new System.Windows.Forms.ComboBox();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // chart
+      // 
+      this.chart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+                  | System.Windows.Forms.AnchorStyles.Left)
+                  | System.Windows.Forms.AnchorStyles.Right)));
+      chartArea1.Name = "ChartArea1";
+      this.chart.ChartAreas.Add(chartArea1);
+      legend1.Alignment = System.Drawing.StringAlignment.Center;
+      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+      legend1.Name = "Legend1";
+      this.chart.Legends.Add(legend1);
+      this.chart.Location = new System.Drawing.Point(6, 28);
+      this.chart.Name = "chart";
+      this.chart.Size = new System.Drawing.Size(366, 202);
+      this.chart.TabIndex = 0;
+      this.chart.Text = "chart";
+      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // label1
+      // 
+      this.label1.AutoSize = true;
+      this.label1.Location = new System.Drawing.Point(3, 6);
+      this.label1.Name = "label1";
+      this.label1.Size = new System.Drawing.Size(47, 13);
+      this.label1.TabIndex = 4;
+      this.label1.Text = "Samples";
+      // 
+      // cmbSamples
+      // 
+      this.cmbSamples.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbSamples.FormattingEnabled = true;
+      this.cmbSamples.Location = new System.Drawing.Point(56, 3);
+      this.cmbSamples.Name = "cmbSamples";
+      this.cmbSamples.Size = new System.Drawing.Size(121, 21);
+      this.cmbSamples.TabIndex = 3;
+      this.cmbSamples.SelectedIndexChanged += new System.EventHandler(this.cmbSamples_SelectedIndexChanged);
+      // 
+      // RegressionSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.label1);
+      this.Controls.Add(this.cmbSamples);
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionErrorCharacteristicsCurveView";
+      this.Size = new System.Drawing.Size(366, 230);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    protected HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+    protected System.Windows.Forms.Label label1;
+    protected System.Windows.Forms.ComboBox cmbSamples;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionErrorCharacteristicsCurveView.cs	(revision 16097)
@@ -0,0 +1,252 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionErrorCharacteristicsCurveView : DataAnalysisSolutionEvaluationView {
+    protected const string TrainingSamples = "Training";
+    protected const string TestSamples = "Test";
+    protected const string AllSamples = "All Samples";
+
+    public RegressionSolutionErrorCharacteristicsCurveView()
+      : base() {
+      InitializeComponent();
+
+      cmbSamples.Items.Add(TrainingSamples);
+      cmbSamples.Items.Add(TestSamples);
+      cmbSamples.Items.Add(AllSamples);
+
+      cmbSamples.SelectedIndex = 0;
+
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].AxisX.Title = "Absolute Error";
+      chart.ChartAreas[0].AxisX.Minimum = 0.0;
+      chart.ChartAreas[0].AxisX.Maximum = 1.0;
+      chart.ChartAreas[0].AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
+      chart.ChartAreas[0].CursorX.Interval = 0.01;
+
+      chart.ChartAreas[0].AxisY.Title = "Number of Samples";
+      chart.ChartAreas[0].AxisY.Minimum = 0.0;
+      chart.ChartAreas[0].AxisY.Maximum = 1.0;
+      chart.ChartAreas[0].AxisY.MajorGrid.Interval = 0.2;
+      chart.ChartAreas[0].CursorY.Interval = 0.01;
+    }
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+    public IRegressionProblemData ProblemData {
+      get {
+        if (Content == null) return null;
+        return Content.ProblemData;
+      }
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected virtual void Content_ModelChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ModelChanged, sender, e);
+      else UpdateChart();
+    }
+    protected virtual void Content_ProblemDataChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)Content_ProblemDataChanged, sender, e);
+      else {
+        UpdateChart();
+      }
+    }
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    protected virtual void UpdateChart() {
+      chart.Series.Clear();
+      chart.Annotations.Clear();
+      if (Content == null) return;
+
+      var constantModel = CreateConstantModel();
+      var originalValues = GetOriginalValues().ToList();
+      var baselineEstimatedValues = GetEstimatedValues(constantModel);
+      var baselineResiduals = GetResiduals(originalValues, baselineEstimatedValues);
+
+      baselineResiduals.Sort();
+      chart.ChartAreas[0].AxisX.Maximum = Math.Ceiling(baselineResiduals.Last());
+      chart.ChartAreas[0].CursorX.Interval = baselineResiduals.First() / 100;
+
+      Series baselineSeries = new Series("Baseline");
+      baselineSeries.ChartType = SeriesChartType.FastLine;
+      UpdateSeries(baselineResiduals, baselineSeries);
+      baselineSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(baselineSeries);
+      baselineSeries.Tag = constantModel;
+      baselineSeries.LegendToolTip = "Double-click to open model";
+      chart.Series.Add(baselineSeries);
+
+      AddRegressionSolution(Content);
+    }
+
+    protected void AddRegressionSolution(IRegressionSolution solution) {
+      if (chart.Series.Any(s => s.Name == solution.Name)) return;
+
+      Series solutionSeries = new Series(solution.Name);
+      solutionSeries.Tag = solution;
+      solutionSeries.ChartType = SeriesChartType.FastLine;
+      var estimatedValues = GetResiduals(GetOriginalValues(), GetEstimatedValues(solution));
+      UpdateSeries(estimatedValues, solutionSeries);
+      solutionSeries.ToolTip = "Area over Curve: " + CalculateAreaOverCurve(solutionSeries);
+      solutionSeries.LegendToolTip = "Double-click to open model";
+      chart.Series.Add(solutionSeries);
+    }
+
+    protected void UpdateSeries(List<double> residuals, Series series) {
+      series.Points.Clear();
+      residuals.Sort();
+      if (!residuals.Any() || residuals.All(double.IsNaN)) return;
+
+      series.Points.AddXY(0, 0);
+      for (int i = 0; i < residuals.Count; i++) {
+        var point = new DataPoint();
+        if (residuals[i] > chart.ChartAreas[0].AxisX.Maximum) {
+          point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+          point.YValues[0] = ((double)i) / residuals.Count;
+          point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+          series.Points.Add(point);
+          break;
+        }
+
+        point.XValue = residuals[i];
+        point.YValues[0] = ((double)i + 1) / residuals.Count;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+
+      if (series.Points.Last().XValue < chart.ChartAreas[0].AxisX.Maximum) {
+        var point = new DataPoint();
+        point.XValue = chart.ChartAreas[0].AxisX.Maximum;
+        point.YValues[0] = 1;
+        point.ToolTip = "Error: " + point.XValue + "\n" + "Samples: " + point.YValues[0];
+        series.Points.Add(point);
+      }
+    }
+
+    protected IEnumerable<double> GetOriginalValues() {
+      IEnumerable<double> originalValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
+          break;
+        case TestSamples:
+          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices);
+          break;
+        case AllSamples:
+          originalValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable);
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return originalValues;
+    }
+
+    protected IEnumerable<double> GetEstimatedValues(IRegressionSolution solution) {
+      IEnumerable<double> estimatedValues;
+      switch (cmbSamples.SelectedItem.ToString()) {
+        case TrainingSamples:
+          estimatedValues = solution.EstimatedTrainingValues;
+          break;
+        case TestSamples:
+          estimatedValues = solution.EstimatedTestValues;
+          break;
+        case AllSamples:
+          estimatedValues = solution.EstimatedValues;
+          break;
+        default:
+          throw new NotSupportedException();
+      }
+      return estimatedValues;
+    }
+
+    protected virtual List<double> GetResiduals(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues) {
+      return originalValues.Zip(estimatedValues, (x, y) => Math.Abs(x - y)).ToList();
+    }
+
+    private double CalculateAreaOverCurve(Series series) {
+      if (series.Points.Count < 1) return 0;
+
+      double auc = 0.0;
+      for (int i = 1; i < series.Points.Count; i++) {
+        double width = series.Points[i].XValue - series.Points[i - 1].XValue;
+        double y1 = 1 - series.Points[i - 1].YValues[0];
+        double y2 = 1 - series.Points[i].YValues[0];
+
+        auc += (y1 + y2) * width / 2;
+      }
+
+      return auc;
+    }
+
+    protected void cmbSamples_SelectedIndexChanged(object sender, EventArgs e) {
+      if (InvokeRequired) Invoke((Action<object, EventArgs>)cmbSamples_SelectedIndexChanged, sender, e);
+      else UpdateChart();
+    }
+
+    #region Baseline
+    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType != ChartElementType.LegendItem) return;
+
+      MainFormManager.MainForm.ShowContent((IRegressionSolution)result.Series.Tag);
+    }
+
+    private IRegressionSolution CreateConstantModel() {
+      double averageTrainingTarget = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
+      var solution = new ConstantRegressionModel(averageTrainingTarget).CreateRegressionSolution(ProblemData);
+      solution.Name = "Baseline";
+      return solution;
+    }
+    #endregion
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        Cursor = Cursors.Hand;
+      } else {
+        Cursor = Cursors.Default;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.Designer.cs	(revision 16097)
@@ -0,0 +1,62 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionEstimatedValuesView {
+    /// <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() {
+      this.SuspendLayout();
+      // 
+      // EstimatedValuesView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "EstimatedValuesView";
+      this.Size = new System.Drawing.Size(310, 285);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionEstimatedValuesView.cs	(revision 16097)
@@ -0,0 +1,125 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Data;
+using HeuristicLab.Data.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Estimated Values")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionEstimatedValuesView : DataAnalysisSolutionEvaluationView {
+    private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
+    private const string ESTIMATEDVALUES_SERIES_NAME = "Estimated Values (all)";
+    private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
+    private const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Values (test)";
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set {
+        base.Content = value;
+      }
+    }
+
+    private StringConvertibleMatrixView matrixView;
+
+    public RegressionSolutionEstimatedValuesView()
+      : base() {
+      InitializeComponent();
+      matrixView = new StringConvertibleMatrixView();
+      matrixView.ShowRowsAndColumnsTextBox = false;
+      matrixView.ShowStatisticalInformation = false;
+      matrixView.Dock = DockStyle.Fill;
+      this.Controls.Add(matrixView);
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateEstimatedValues();
+    }
+
+    private void UpdateEstimatedValues() {
+      if (InvokeRequired) Invoke((Action)UpdateEstimatedValues);
+      else {
+        StringMatrix matrix = null;
+        if (Content != null) {
+          string[,] values = new string[Content.ProblemData.Dataset.Rows, 7];
+
+          double[] target = Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray();
+          var estimated = Content.EstimatedValues.GetEnumerator();
+          var estimated_training = Content.EstimatedTrainingValues.GetEnumerator();
+          var estimated_test = Content.EstimatedTestValues.GetEnumerator();
+
+          foreach (var row in Content.ProblemData.TrainingIndices) {
+            estimated_training.MoveNext();
+            values[row, 3] = estimated_training.Current.ToString();
+          }
+
+          foreach (var row in Content.ProblemData.TestIndices) {
+            estimated_test.MoveNext();
+            values[row, 4] = estimated_test.Current.ToString();
+          }
+
+          foreach (var row in Enumerable.Range(0, Content.ProblemData.Dataset.Rows)) {
+            estimated.MoveNext();
+            double est = estimated.Current;
+            double res = Math.Abs(est - target[row]);
+            values[row, 0] = row.ToString();
+            values[row, 1] = target[row].ToString();
+            values[row, 2] = est.ToString();
+            values[row, 5] = Math.Abs(res).ToString();
+            values[row, 6] = Math.Abs(res / est).ToString();
+          }
+
+          matrix = new StringMatrix(values);
+          matrix.ColumnNames = new string[] { "Id", TARGETVARIABLE_SERIES_NAME, ESTIMATEDVALUES_SERIES_NAME, ESTIMATEDVALUES_TRAINING_SERIES_NAME, ESTIMATEDVALUES_TEST_SERIES_NAME, "Absolute Error (all)", "Relative Error (all)" };
+          matrix.SortableView = true;
+        }
+        matrixView.Content = matrix;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.Designer.cs	(revision 16097)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionLineChartView {
+    /// <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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((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.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.Chart_MouseDoubleClick);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // RegressionSolutionLineChartView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionLineChartView";
+      this.Size = new System.Drawing.Size(358, 225);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionLineChartView.cs	(revision 16097)
@@ -0,0 +1,284 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Line Chart")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionLineChartView : DataAnalysisSolutionEvaluationView {
+    private const string TARGETVARIABLE_SERIES_NAME = "Target Variable";
+    private const string ESTIMATEDVALUES_TRAINING_SERIES_NAME = "Estimated Values (training)";
+    private const string ESTIMATEDVALUES_TEST_SERIES_NAME = "Estimated Values (test)";
+    private const string ESTIMATEDVALUES_ALL_SERIES_NAME = "Estimated Values (all samples)";
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionSolutionLineChartView()
+      : base() {
+      InitializeComponent();
+      //configure axis
+      this.chart.CustomizeAllChartAreas();
+      this.chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].AxisX.IsStartedFromZero = true;
+      this.chart.ChartAreas[0].CursorX.Interval = 1;
+
+      this.chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      this.chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      this.chart.ChartAreas[0].CursorY.Interval = 0;
+    }
+
+    private void RedrawChart() {
+      this.chart.Series.Clear();
+      if (Content != null) {
+        this.chart.ChartAreas[0].AxisX.Minimum = 0;
+        this.chart.ChartAreas[0].AxisX.Maximum = Content.ProblemData.Dataset.Rows - 1;
+
+        this.chart.Series.Add(TARGETVARIABLE_SERIES_NAME);
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].LegendText = Content.ProblemData.TargetVariable;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.DataBindXY(Enumerable.Range(0, Content.ProblemData.Dataset.Rows).ToArray(),
+          Content.ProblemData.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToArray());
+        // training series
+        this.chart.Series.Add(ESTIMATEDVALUES_TRAINING_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].LegendText = ESTIMATEDVALUES_TRAINING_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].EmptyPointStyle.Color = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Color;
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TrainingIndices.ToArray(), Content.EstimatedTrainingValues.ToArray());
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Tag = Content;
+        // test series
+        this.chart.Series.Add(ESTIMATEDVALUES_TEST_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].LegendText = ESTIMATEDVALUES_TEST_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.DataBindXY(Content.ProblemData.TestIndices.ToArray(), Content.EstimatedTestValues.ToArray());
+        this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME]);
+        this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Tag = Content;
+        // series of remaining points
+        int[] allIndices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
+        var estimatedValues = Content.EstimatedValues.ToArray();
+        List<double> allEstimatedValues = allIndices.Select(index => estimatedValues[index]).ToList();
+        this.chart.Series.Add(ESTIMATEDVALUES_ALL_SERIES_NAME);
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].LegendText = ESTIMATEDVALUES_ALL_SERIES_NAME;
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].ChartType = SeriesChartType.FastLine;
+        if (allEstimatedValues.Count > 0) {
+          this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.DataBindXY(allIndices, allEstimatedValues);
+          this.InsertEmptyPoints(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+        }
+        this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Tag = Content;
+        this.ToggleSeriesData(this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME]);
+
+        UpdateCursorInterval();
+        this.UpdateStripLines();
+      }
+    }
+
+    private void InsertEmptyPoints(Series series) {
+      int i = 0;
+      while (i < series.Points.Count - 1) {
+        if (series.Points[i].IsEmpty) {
+          ++i;
+          continue;
+        }
+
+        var p1 = series.Points[i];
+        var p2 = series.Points[i + 1];
+        // check for consecutive indices
+        if ((int)p2.XValue - (int)p1.XValue != 1) {
+          // insert an empty point between p1 and p2 so that the line will be invisible (transparent)
+          var p = new DataPoint((int)((p1.XValue + p2.XValue) / 2), 0.0) { IsEmpty = true };
+          series.Points.Insert(i + 1, p);
+        }
+        ++i;
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      var targetValues = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
+      double targetValuesRange = targetValues.Max() - targetValues.Min();
+      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double yZoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
+      this.chart.ChartAreas[0].CursorY.Interval = yZoomInterval;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+
+
+
+    private void Chart_MouseDoubleClick(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartArea != null && (result.ChartElementType == ChartElementType.PlottingArea ||
+                                       result.ChartElementType == ChartElementType.Gridlines) ||
+                                       result.ChartElementType == ChartElementType.StripLines) {
+        foreach (var axis in result.ChartArea.Axes)
+          axis.ScaleView.ZoomReset(int.MaxValue);
+      }
+    }
+    #endregion
+
+    private void UpdateStripLines() {
+      this.chart.ChartAreas[0].AxisX.StripLines.Clear();
+
+      int[] attr = new int[Content.ProblemData.Dataset.Rows + 1]; // add a virtual last row that is again empty to simplify loop further down
+      foreach (var row in Content.ProblemData.TrainingIndices) {
+        attr[row] += 1;
+      }
+      foreach (var row in Content.ProblemData.TestIndices) {
+        attr[row] += 2;
+      }
+      int start = 0;
+      int curAttr = attr[start];
+      for (int row = 0; row < attr.Length; row++) {
+        if (attr[row] != curAttr) {
+          switch (curAttr) {
+            case 0: break;
+            case 1:
+              this.CreateAndAddStripLine("Training", start, row, Color.FromArgb(40, Color.Green), Color.Transparent);
+              break;
+            case 2:
+              this.CreateAndAddStripLine("Test", start, row, Color.FromArgb(40, Color.Red), Color.Transparent);
+              break;
+            case 3:
+              this.CreateAndAddStripLine("Training and Test", start, row, Color.FromArgb(40, Color.Green), Color.FromArgb(40, Color.Red), ChartHatchStyle.WideUpwardDiagonal);
+              break;
+            default:
+              // should not happen
+              break;
+          }
+          curAttr = attr[row];
+          start = row;
+        }
+      }
+    }
+
+    private void CreateAndAddStripLine(string title, int start, int end, Color color, Color secondColor, ChartHatchStyle hatchStyle = ChartHatchStyle.None) {
+      StripLine stripLine = new StripLine();
+      stripLine.BackColor = color;
+      stripLine.BackSecondaryColor = secondColor;
+      stripLine.BackHatchStyle = hatchStyle;
+      stripLine.Text = title;
+      stripLine.Font = new Font("Times New Roman", 12, FontStyle.Bold);
+      // strip range is [start .. end] inclusive, but we evaluate [start..end[ (end is exclusive)
+      // the strip should be by one longer (starting at start - 0.5 and ending at end + 0.5)
+      stripLine.StripWidth = end - start;
+      stripLine.IntervalOffset = start - 0.5; // start slightly to the left of the first point to clearly indicate the first point in the partition
+      this.chart.ChartAreas[0].AxisX.StripLines.Add(stripLine);
+    }
+
+    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)) {
+          ClearPointsQuick(series.Points);
+        }
+      } else if (Content != null) {
+        string targetVariableName = Content.ProblemData.TargetVariable;
+
+        IEnumerable<int> indices = null;
+        double[] predictedValues = null;
+        switch (series.Name) {
+          case ESTIMATEDVALUES_ALL_SERIES_NAME:
+            indices = Enumerable.Range(0, Content.ProblemData.Dataset.Rows).Except(Content.ProblemData.TrainingIndices).Except(Content.ProblemData.TestIndices).ToArray();
+            var estimatedValues = Content.EstimatedValues.ToArray();
+            predictedValues = indices.Select(index => estimatedValues[index]).ToArray();
+            break;
+          case ESTIMATEDVALUES_TRAINING_SERIES_NAME:
+            indices = Content.ProblemData.TrainingIndices.ToArray();
+            predictedValues = Content.EstimatedTrainingValues.ToArray();
+            break;
+          case ESTIMATEDVALUES_TEST_SERIES_NAME:
+            indices = Content.ProblemData.TestIndices.ToArray();
+            predictedValues = Content.EstimatedTestValues.ToArray();
+            break;
+        }
+        if (predictedValues.Length > 0) {
+          series.Points.DataBindXY(indices, predictedValues);
+          this.InsertEmptyPoints(series);
+        }
+        chart.Legends[series.Legend].ForeColor = Color.Black;
+        UpdateCursorInterval();
+        chart.Refresh();
+      }
+    }
+
+    // workaround as per http://stackoverflow.com/questions/5744930/datapointcollection-clear-performance
+    private static void ClearPointsQuick(DataPointCollection points) {
+      points.SuspendUpdates();
+      while (points.Count > 0)
+        points.RemoveAt(points.Count - 1);
+      points.ResumeUpdates();
+    }
+
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME)
+        Cursor = Cursors.Hand;
+      else
+        Cursor = Cursors.Default;
+    }
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem && result.Series.Name != TARGETVARIABLE_SERIES_NAME) {
+        ToggleSeriesData(result.Series);
+      }
+    }
+
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      if (chart.Series.Count != 4) return;
+      e.LegendItems[0].Cells[1].ForeColor = this.chart.Series[TARGETVARIABLE_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TRAINING_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_TEST_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[3].Cells[1].ForeColor = this.chart.Series[ESTIMATEDVALUES_ALL_SERIES_NAME].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.Designer.cs	(revision 16097)
@@ -0,0 +1,65 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionResidualHistogram {
+    /// <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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((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(289, 220);
+      this.chart.TabIndex = 0;
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // RegressionSolutionResidualHistogram
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionResidualHistogram";
+      this.Size = new System.Drawing.Size(289, 220);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionResidualHistogram.cs	(revision 16097)
@@ -0,0 +1,235 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Residual Histogram")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionResidualHistogram : DataAnalysisSolutionEvaluationView {
+
+    #region variables
+    protected const string ALL_SAMPLES = "All samples";
+    protected const string TRAINING_SAMPLES = "Training samples";
+    protected const string TEST_SAMPLES = "Test samples";
+    /// <summary>
+    /// approximate amount of bins 
+    /// </summary>
+    protected const double bins = 25;
+    #endregion
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionSolutionResidualHistogram()
+      : base() {
+      InitializeComponent();
+      foreach (string series in new List<String>() { ALL_SAMPLES, TRAINING_SAMPLES, TEST_SAMPLES }) {
+        chart.Series.Add(series);
+        chart.Series[series].LegendText = series;
+        chart.Series[series].ChartType = SeriesChartType.Column;
+        chart.Series[series]["PointWidth"] = "0.9";
+        chart.Series[series].BorderWidth = 1;
+        chart.Series[series].BorderDashStyle = ChartDashStyle.Solid;
+        chart.Series[series].BorderColor = Color.Black;
+        chart.Series[series].ToolTip = series + " Y = #VALY from #CUSTOMPROPERTY(from) to #CUSTOMPROPERTY(to)";
+      }
+      //configure axis 
+      chart.CustomizeAllChartAreas();
+      chart.ChartAreas[0].AxisX.Title = "Residuals";
+      chart.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].CursorX.Interval = 1;
+      chart.ChartAreas[0].CursorY.Interval = 1;
+      chart.ChartAreas[0].AxisY.Title = "Relative Frequency";
+      chart.ChartAreas[0].CursorY.IsUserSelectionEnabled = true;
+      chart.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
+      chart.ChartAreas[0].AxisY.IsStartedFromZero = true;
+    }
+
+    private void RedrawChart() {
+      foreach (Series series in chart.Series) {
+        series.Points.Clear();
+      }
+      if (Content != null) {
+        List<double> residuals = CalculateResiduals(Content);
+
+        double max = 0.0;
+        foreach (Series series in chart.Series) {
+          CalculateFrequencies(residuals, series);
+          double seriesMax = series.Points.Select(p => p.YValues.First()).Max();
+          max = max < seriesMax ? seriesMax : max;
+        }
+
+        // ALL_SAMPLES has to be calculated to know its highest frequency, but it is not shown in the beginning
+        chart.Series.First(s => s.Name.Equals(ALL_SAMPLES)).Points.Clear();
+
+        double roundedMax, intervalWidth;
+        CalculateResidualParameters(residuals, out roundedMax, out intervalWidth);
+
+        ChartArea chartArea = chart.ChartAreas[0];
+        chartArea.AxisX.Minimum = -roundedMax - intervalWidth;
+        chartArea.AxisX.Maximum = roundedMax + intervalWidth;
+        // get the highest frequency of a residual of any series
+        chartArea.AxisY.Maximum = max;
+        if (chartArea.AxisY.Maximum < 0.1) {
+          chartArea.AxisY.Interval = 0.01;
+          chartArea.AxisY.Maximum = Math.Ceiling(chartArea.AxisY.Maximum * 100) / 100;
+        } else {
+          chartArea.AxisY.Interval = 0.1;
+          chartArea.AxisY.Maximum = Math.Ceiling(chartArea.AxisY.Maximum * 10) / 10;
+        }
+        chartArea.AxisX.Interval = intervalWidth;
+        int curBins = (int)Math.Round((roundedMax * 2) / intervalWidth);
+        //shifts the x axis label so that zero is in the middle
+        if (curBins % 2 == 0)
+          chartArea.AxisX.IntervalOffset = intervalWidth;
+        else
+          chartArea.AxisX.IntervalOffset = intervalWidth / 2;
+      }
+    }
+
+    private List<double> CalculateResiduals(IRegressionSolution solution) {
+      List<double> residuals = new List<double>();
+
+      IRegressionProblemData problemdata = solution.ProblemData;
+      List<double> targetValues = problemdata.Dataset.GetDoubleValues(Content.ProblemData.TargetVariable).ToList();
+      List<double> estimatedValues = solution.EstimatedValues.ToList();
+
+      for (int i = 0; i < solution.ProblemData.Dataset.Rows; i++) {
+        double residual = estimatedValues[i] - targetValues[i];
+        residuals.Add(residual);
+      }
+      return residuals;
+    }
+
+    private void CalculateFrequencies(List<double> residualValues, Series series) {
+      double roundedMax, intervalWidth;
+      CalculateResidualParameters(residualValues, out roundedMax, out intervalWidth);
+
+      IEnumerable<double> relevantResiduals = residualValues;
+      IRegressionProblemData problemdata = Content.ProblemData;
+      if (series.Name.Equals(TRAINING_SAMPLES)) {
+        relevantResiduals = residualValues.Skip(problemdata.TrainingPartition.Start).Take(problemdata.TrainingPartition.Size);
+      } else if (series.Name.Equals(TEST_SAMPLES)) {
+        relevantResiduals = residualValues.Skip(problemdata.TestPartition.Start).Take(problemdata.TestPartition.Size);
+      }
+
+      double intervalCenter = intervalWidth / 2.0;
+      double sampleCount = relevantResiduals.Count();
+      double current = -roundedMax;
+      DataPointCollection seriesPoints = series.Points;
+
+      for (int i = 0; i <= bins; i++) {
+        IEnumerable<double> help = relevantResiduals.Where(x => x >= (current - intervalCenter) && x < (current + intervalCenter));
+        seriesPoints.AddXY(current, help.Count() / sampleCount);
+        seriesPoints[seriesPoints.Count - 1]["from"] = (current - intervalCenter).ToString();
+        seriesPoints[seriesPoints.Count - 1]["to"] = (current + intervalCenter).ToString();
+        current += intervalWidth;
+      }
+    }
+
+    private void ToggleSeriesData(Series series) {
+      if (series.Points.Count > 0) {  //checks if series is shown
+        if (chart.Series.Any(s => s != series && s.Points.Count > 0)) {
+          series.Points.Clear();
+        }
+      } else if (Content != null) {
+        List<double> residuals = CalculateResiduals(Content);
+        CalculateFrequencies(residuals, series);
+        chart.Legends[series.Legend].ForeColor = Color.Black;
+        chart.Refresh();
+      }
+    }
+
+    private static void CalculateResidualParameters(List<double> residuals, out double roundedMax, out double intervalWidth) {
+      double realMax = Math.Max(Math.Abs(residuals.Min()), Math.Abs(residuals.Max()));
+      roundedMax = HumanRoundMax(realMax);
+      intervalWidth = (roundedMax * 2.0) / bins;
+      intervalWidth = HumanRoundMax(intervalWidth);
+      // sets roundedMax to a value, so that zero will be in the middle of the x axis
+      double help = realMax / intervalWidth;
+      help = help % 1 < 0.5 ? (int)help : (int)help + 1;
+      roundedMax = help * intervalWidth;
+    }
+
+    private static double HumanRoundMax(double max) {
+      double base10;
+      if (max > 0) base10 = Math.Pow(10.0, Math.Floor(Math.Log10(max)));
+      else base10 = Math.Pow(10.0, Math.Ceiling(Math.Log10(-max)));
+      double rounding = (max > 0) ? base10 : -base10;
+      while (rounding < max) rounding += base10;
+      return rounding;
+    }
+
+    #region events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      RedrawChart();
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      RedrawChart();
+    }
+    private void chart_MouseDown(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem) {
+        ToggleSeriesData(result.Series);
+      }
+    }
+    private void chart_MouseMove(object sender, MouseEventArgs e) {
+      HitTestResult result = chart.HitTest(e.X, e.Y);
+      if (result.ChartElementType == ChartElementType.LegendItem)
+        Cursor = Cursors.Hand;
+      else
+        Cursor = Cursors.Default;
+    }
+    private void chart_CustomizeLegend(object sender, CustomizeLegendEventArgs e) {
+      if (chart.Series.Count != 3) return;
+      e.LegendItems[0].Cells[1].ForeColor = chart.Series[ALL_SAMPLES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[1].Cells[1].ForeColor = chart.Series[TRAINING_SAMPLES].Points.Count == 0 ? Color.Gray : Color.Black;
+      e.LegendItems[2].Cells[1].ForeColor = chart.Series[TEST_SAMPLES].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.Designer.cs	(revision 16097)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionScatterPlotView {
+    /// <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 HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+      ((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.PostPaint += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.ChartPaintEventArgs>(this.chart_PostPaint);
+      this.chart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+      this.chart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+      this.chart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+      // 
+      // RegressionSolutionScatterPlotView
+      // 
+      this.AllowDrop = true;
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.Controls.Add(this.chart);
+      this.Name = "RegressionSolutionScatterPlotView";
+      this.Size = new System.Drawing.Size(527, 392);
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart chart;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionSolutionScatterPlotView.cs	(revision 16097)
@@ -0,0 +1,262 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using System.Windows.Forms.DataVisualization.Charting;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Scatter Plot")]
+  [Content(typeof(IRegressionSolution))]
+  public partial class RegressionSolutionScatterPlotView : DataAnalysisSolutionEvaluationView {
+    private const string ALL_SERIES = "All samples";
+    private const string TRAINING_SERIES = "Training samples";
+    private const string TEST_SERIES = "Test samples";
+
+    public new IRegressionSolution Content {
+      get { return (IRegressionSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionSolutionScatterPlotView()
+      : base() {
+      InitializeComponent();
+
+      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[TRAINING_SERIES].Points.Add(1.0);
+
+      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.CustomizeAllChartAreas();
+      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 = 1;
+      this.chart.ChartAreas[0].CursorY.Interval = 1;
+
+      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;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ModelChanged += new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ModelChanged -= new EventHandler(Content_ModelChanged);
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+
+
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      UpdateChart();
+    }
+    private void Content_ModelChanged(object sender, EventArgs e) {
+      UpdateSeries();
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      UpdateChart();
+    }
+
+    private void UpdateChart() {
+      if (InvokeRequired) Invoke((Action)UpdateChart);
+      else {
+        if (Content != null) {
+          this.UpdateSeries();
+          if (!this.chart.Series.Any(s => s.Points.Count > 0))
+            this.ClearChart();
+        }
+      }
+    }
+
+    private void UpdateCursorInterval() {
+      var estimatedValues = this.chart.Series[ALL_SERIES].Points.Select(x => x.XValue).DefaultIfEmpty(1.0);
+      var targetValues = this.chart.Series[ALL_SERIES].Points.Select(x => x.YValues[0]).DefaultIfEmpty(1.0);
+      double estimatedValuesRange = estimatedValues.Max() - estimatedValues.Min();
+      double targetValuesRange = targetValues.Max() - targetValues.Min();
+      double interestingValuesRange = Math.Min(Math.Max(targetValuesRange, 1.0), Math.Max(estimatedValuesRange, 1.0));
+      double digits = (int)Math.Log10(interestingValuesRange) - 3;
+      double zoomInterval = Math.Max(Math.Pow(10, digits), 10E-5);
+      this.chart.ChartAreas[0].CursorX.Interval = zoomInterval;
+      this.chart.ChartAreas[0].CursorY.Interval = zoomInterval;
+
+      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollSize = zoomInterval;
+      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = zoomInterval;
+
+      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
+      this.chart.ChartAreas[0].AxisX.ScaleView.SmallScrollMinSize = zoomInterval;
+      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSizeType = DateTimeIntervalType.Number;
+      this.chart.ChartAreas[0].AxisY.ScaleView.SmallScrollMinSize = zoomInterval;
+
+      if (digits < 0) {
+        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F" + (int)Math.Abs(digits);
+        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F" + (int)Math.Abs(digits);
+      } else {
+        this.chart.ChartAreas[0].AxisX.LabelStyle.Format = "F0";
+        this.chart.ChartAreas[0].AxisY.LabelStyle.Format = "F0";
+      }
+    }
+
+
+    private void UpdateSeries() {
+      if (InvokeRequired) Invoke((Action)UpdateSeries);
+      else {
+        string targetVariableName = Content.ProblemData.TargetVariable;
+        Dataset dataset = Content.ProblemData.Dataset;
+        if (this.chart.Series[ALL_SERIES].Points.Count > 0)
+          this.chart.Series[ALL_SERIES].Points.DataBindXY(Content.EstimatedValues.ToArray(), "",
+            dataset.GetDoubleValues(targetVariableName).ToArray(), "");
+        if (this.chart.Series[TRAINING_SERIES].Points.Count > 0)
+          this.chart.Series[TRAINING_SERIES].Points.DataBindXY(Content.EstimatedTrainingValues.ToArray(), "",
+            dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray(), "");
+        if (this.chart.Series[TEST_SERIES].Points.Count > 0)
+          this.chart.Series[TEST_SERIES].Points.DataBindXY(Content.EstimatedTestValues.ToArray(), "",
+           dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray(), "");
+
+        double max = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Max();
+        double min = Content.EstimatedTrainingValues.Concat(Content.EstimatedTestValues.Concat(Content.EstimatedValues.Concat(dataset.GetDoubleValues(targetVariableName)))).Min();
+
+        max = max + 0.2 * Math.Abs(max);
+        min = min - 0.2 * Math.Abs(min);
+
+        double interestingValuesRange = max - min;
+        int digits = Math.Max(0, 3 - (int)Math.Log10(interestingValuesRange));
+
+        max = Math.Round(max, digits);
+        min = Math.Round(min, digits);
+
+        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;
+        UpdateCursorInterval();
+      }
+    }
+
+    private void ClearChart() {
+      this.chart.Series[ALL_SERIES].Points.Clear();
+      this.chart.Series[TRAINING_SERIES].Points.Clear();
+      this.chart.Series[TEST_SERIES].Points.Clear();
+    }
+
+    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 (Content != null) {
+        string targetVariableName = Content.ProblemData.TargetVariable;
+
+        double[] predictedValues = null;
+        double[] targetValues = null;
+        switch (series.Name) {
+          case ALL_SERIES:
+            predictedValues = Content.EstimatedValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName).ToArray();
+            break;
+          case TRAINING_SERIES:
+            predictedValues = Content.EstimatedTrainingValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TrainingIndices).ToArray();
+            break;
+          case TEST_SERIES:
+            predictedValues = Content.EstimatedTestValues.ToArray();
+            targetValues = Content.ProblemData.Dataset.GetDoubleValues(targetVariableName, Content.ProblemData.TestIndices).ToArray();
+            break;
+        }
+        if (predictedValues.Length == targetValues.Length)
+          series.Points.DataBindXY(predictedValues, "", targetValues, "");
+        this.chart.Legends[series.Legend].ForeColor = Color.Black;
+        UpdateCursorInterval();
+      }
+    }
+
+    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[TEST_SERIES].Points.Count == 0 ? Color.Gray : Color.Black;
+    }
+
+    private void chart_PostPaint(object sender, ChartPaintEventArgs e) {
+      var chartArea = e.ChartElement as ChartArea;
+      if (chartArea != null) {
+        ChartGraphics chartGraphics = e.ChartGraphics;
+        using (Pen p = new Pen(Color.DarkGray)) {
+          double xmin = chartArea.AxisX.ScaleView.ViewMinimum;
+          double xmax = chartArea.AxisX.ScaleView.ViewMaximum;
+          double ymin = chartArea.AxisY.ScaleView.ViewMinimum;
+          double ymax = chartArea.AxisY.ScaleView.ViewMaximum;
+
+          if (xmin > ymax || ymin > xmax) return;
+
+          PointF start = PointF.Empty;
+          start.X = (float)chartGraphics.GetPositionFromAxis(chartArea.Name, chartArea.AxisX.AxisName, Math.Max(xmin, ymin));
+          start.Y = (float)chartGraphics.GetPositionFromAxis(chartArea.Name, chartArea.AxisY.AxisName, Math.Max(xmin, ymin));
+          PointF end = PointF.Empty;
+          end.X = (float)chartGraphics.GetPositionFromAxis(chartArea.Name, chartArea.AxisX.AxisName, Math.Min(xmax, ymax));
+          end.Y = (float)chartGraphics.GetPositionFromAxis(chartArea.Name, chartArea.AxisY.AxisName, Math.Min(xmax, ymax));
+
+          chartGraphics.Graphics.DrawLine(p, chartGraphics.GetAbsolutePoint(start), chartGraphics.GetAbsolutePoint(end));
+        }
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.Designer.cs	(revision 16097)
@@ -0,0 +1,32 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionTimeframeFeatureCorrelationView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Regression/RegressionTimeframeFeatureCorrelationView.cs	(revision 16097)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Regression Timeframe Feature Correlation View")]
+  [Content(typeof(RegressionProblemData), false)]
+  public partial class RegressionTimeframeFeatureCorrelationView : TimeframeFeatureCorrelationView {
+
+    public new RegressionProblemData Content {
+      get { return (RegressionProblemData)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public RegressionTimeframeFeatureCorrelationView() {
+      InitializeComponent();
+    }
+
+    protected override bool[] SetInitialVariableVisibility() {
+      int i = Content.Dataset.DoubleVariables.ToList().FindIndex(x => x == Content.TargetVariable);
+      var initialVisibility = base.SetInitialVariableVisibility();
+      initialVisibility[i] = true;
+      return initialVisibility;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationEnsembleSolutionView {
+    /// <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() {
+      this.cmbWeightCalculator = new System.Windows.Forms.ComboBox();
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel2
+      // 
+      this.splitContainer.Panel2.Controls.Add(this.cmbWeightCalculator);
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // cmbWeightCalculator
+      // 
+      this.cmbWeightCalculator.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+      this.cmbWeightCalculator.FormattingEnabled = true;
+      this.cmbWeightCalculator.Location = new System.Drawing.Point(9, 6);
+      this.cmbWeightCalculator.Name = "cmbWeightCalculator";
+      this.cmbWeightCalculator.Size = new System.Drawing.Size(180, 21);
+      this.cmbWeightCalculator.TabIndex = 1;
+      this.cmbWeightCalculator.SelectedIndexChanged += new System.EventHandler(this.cmbWeightCalculator_SelectedIndexChanged);
+      // 
+      // ClassificationEnsembleSolutionView
+      // 
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "ClassificationEnsembleSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    protected System.Windows.Forms.ComboBox cmbWeightCalculator;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationEnsembleSolutionView.cs	(revision 16097)
@@ -0,0 +1,83 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ClassificationEnsembleSolution View")]
+  [Content(typeof(ClassificationEnsembleSolution), false)]
+  public partial class ClassificationEnsembleSolutionView : ClassificationSolutionView {
+    public ClassificationEnsembleSolutionView() {
+      InitializeComponent();
+    }
+
+    public new ClassificationEnsembleSolution Content {
+      get { return (ClassificationEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      cmbWeightCalculator.Enabled = !Locked && !ReadOnly && Content != null;
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      itemsListView.Items.Remove(itemsListView.FindItemWithText("Model: ClassificationEnsembleModel"));
+      if (cmbWeightCalculator.Items.Count == 0) {
+        cmbWeightCalculator.Items.AddRange(ApplicationManager.Manager.GetInstances<IClassificationEnsembleSolutionWeightCalculator>().OrderBy(b => b.Name, new NaturalStringComparer()).ToArray());
+        if (cmbWeightCalculator.Items.Count > 0) {
+          cmbWeightCalculator.SelectedIndex = 0;
+        }
+      } else {
+        Content.WeightCalculator = (IClassificationEnsembleSolutionWeightCalculator)cmbWeightCalculator.SelectedItem;
+      }
+    }
+
+    protected void cmbWeightCalculator_SelectedIndexChanged(object sender, System.EventArgs e) {
+      if (cmbWeightCalculator.SelectedItem != null) {
+        Content.WeightCalculator = (IClassificationEnsembleSolutionWeightCalculator)cmbWeightCalculator.SelectedItem;
+      }
+    }
+
+    #region drag & drop
+    protected override void itemsListView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var droppedData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        if (droppedData is IValueParameter) droppedData = ((IValueParameter)droppedData).Value;
+
+        ClassificationEnsembleProblemData ensembleProblemData = droppedData as ClassificationEnsembleProblemData;
+        ClassificationProblemData problemData = droppedData as ClassificationProblemData;
+        if (ensembleProblemData != null) {
+          Content.ProblemData = (ClassificationEnsembleProblemData)ensembleProblemData.Clone();
+        } else if (problemData != null) {
+          Content.ProblemData = new ClassificationEnsembleProblemData((IClassificationProblemData)problemData.Clone());
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,54 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClassificationSolutionView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.itemsGroupBox.Text = "Classification Solution";
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClassificationSolutionView.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ClassificationSolution View")]
+  [Content(typeof(ClassificationSolutionBase), false)]
+  public partial class ClassificationSolutionView : DataAnalysisSolutionView {
+    public ClassificationSolutionView() {
+      InitializeComponent();
+    }
+
+    public new ClassificationSolutionBase Content {
+      get { return (ClassificationSolutionBase)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is ClassificationProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is ClassificationProblemData) validDragOperation = true;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,86 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class ClusteringSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Clustering Solution";
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // RegressionSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "ClusteringSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/ClusteringSolutionView.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ClusteringSolution View")]
+  [Content(typeof(ClusteringSolution), false)]
+  public partial class ClusteringSolutionView : DataAnalysisSolutionView {
+    public ClusteringSolutionView() {
+      InitializeComponent();
+    }
+
+    public new ClusteringSolution Content {
+      get { return (ClusteringSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is ClusteringProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is ClusteringProblemData) validDragOperation = true;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,87 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DataAnalysisSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Data Analysis Solution";
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // DataAnalysisSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "DataAnalysisSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DataAnalysisSolutionView.cs	(revision 16097)
@@ -0,0 +1,192 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("DataAnalysisSolution View")]
+  [Content(typeof(DataAnalysisSolution), false)]
+  public partial class DataAnalysisSolutionView : NamedItemCollectionView<IResult> {
+    public DataAnalysisSolutionView() {
+      InitializeComponent();
+      viewHost.ViewsLabelVisible = false;
+    }
+
+    public new DataAnalysisSolution Content {
+      get { return (DataAnalysisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      addButton.Enabled = false;
+      removeButton.Enabled = false;
+    }
+
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.ProblemDataChanged += new EventHandler(Content_ProblemDataChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      base.DeregisterContentEvents();
+      Content.ProblemDataChanged -= new EventHandler(Content_ProblemDataChanged);
+    }
+    private void Content_ProblemDataChanged(object sender, EventArgs e) {
+      OnContentChanged();
+    }
+
+    protected override void OnContentChanged() {
+      string selectedName = null;
+      if ((itemsListView.SelectedItems.Count == 1) && (itemsListView.SelectedItems[0].Tag != null && itemsListView.SelectedItems[0].Tag is Type))
+        selectedName = itemsListView.SelectedItems[0].Text;
+
+      base.OnContentChanged();
+      AddEvaluationViewTypes();
+
+      //recover selection
+      if (selectedName != null) {
+        foreach (ListViewItem item in itemsListView.Items) {
+          if (item.Tag != null && item.Tag is Type && item.Text == selectedName)
+            item.Selected = true;
+        }
+      }
+    }
+
+    protected override IResult CreateItem() {
+      return null;
+    }
+
+    protected virtual void AddEvaluationViewTypes() {
+      if (Content != null && !Content.ProblemData.IsEmpty) {
+        var viewTypes = MainFormManager.GetViewTypes(Content.GetType(), true)
+          .Where(t => typeof(IDataAnalysisSolutionEvaluationView).IsAssignableFrom(t));
+        foreach (var viewType in viewTypes)
+          AddViewListViewItem(viewType, ((IDataAnalysisSolutionEvaluationView)Activator.CreateInstance(viewType)).ViewImage);
+      }
+    }
+
+    protected override void itemsListView_DoubleClick(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count != 1) return;
+
+      IResult result = itemsListView.SelectedItems[0].Tag as IResult;
+      Type viewType = itemsListView.SelectedItems[0].Tag as Type;
+      if (result != null) {
+        IContentView view = MainFormManager.MainForm.ShowContent(result, typeof(ResultView));
+        if (view != null) {
+          view.ReadOnly = ReadOnly;
+          view.Locked = Locked;
+        }
+      } else if (viewType != null) {
+        MainFormManager.MainForm.ShowContent(Content, viewType);
+      }
+    }
+
+    protected override void itemsListView_SelectedIndexChanged(object sender, EventArgs e) {
+      if (itemsListView.SelectedItems.Count == 1 && itemsListView.SelectedItems[0].Tag is Type) {
+        detailsGroupBox.Enabled = true;
+        Type viewType = (Type)itemsListView.SelectedItems[0].Tag;
+        viewHost.ViewType = viewType;
+        viewHost.Content = Content;
+      } else
+        base.itemsListView_SelectedIndexChanged(sender, e);
+    }
+
+    protected void AddViewListViewItem(Type viewType, Image image) {
+      ListViewItem listViewItem = new ListViewItem();
+      listViewItem.Text = ViewAttribute.GetViewName(viewType);
+      itemsListView.SmallImageList.Images.Add(image);
+      listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+      listViewItem.Tag = viewType;
+      itemsListView.Items.Add(listViewItem);
+
+      AdjustListViewColumnSizes();
+    }
+
+    protected void RemoveViewListViewItem(Type viewType) {
+      List<ListViewItem> itemsToRemove = itemsListView.Items.Cast<ListViewItem>().Where(item => item.Tag as Type == viewType).ToList();
+
+      foreach (ListViewItem item in itemsToRemove)
+        itemsListView.Items.Remove(item);
+    }
+
+    protected override void showDetailsCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (showDetailsCheckBox.Checked && itemsListView.SelectedItems.Count == 1 && itemsListView.SelectedItems[0].Tag is Type) {
+        Type viewType = (Type)itemsListView.SelectedItems[0].Tag;
+        viewHost.ViewType = viewType;
+        viewHost.Content = Content;
+        splitContainer.Panel2Collapsed = false;
+        detailsGroupBox.Enabled = true;
+      } else base.showDetailsCheckBox_CheckedChanged(sender, e);
+    }
+
+    protected override void RebuildImageList() {
+      itemsListView.SmallImageList.Images.Clear();
+      foreach (ListViewItem listViewItem in itemsListView.Items) {
+        IResult result = listViewItem.Tag as IResult;
+        Type viewType = listViewItem.Tag as Type;
+        if (result != null) itemsListView.SmallImageList.Images.Add(result.ItemImage);
+        else if (viewType != null && typeof(IDataAnalysisSolutionEvaluationView).IsAssignableFrom(viewType))
+          itemsListView.SmallImageList.Images.Add(((IDataAnalysisSolutionEvaluationView)Activator.CreateInstance(viewType)).ViewImage);
+        else itemsListView.SmallImageList.Images.Add(HeuristicLab.Common.Resources.VSImageLibrary.Nothing);
+
+        listViewItem.ImageIndex = itemsListView.SmallImageList.Images.Count - 1;
+      }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is DataAnalysisProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is DataAnalysisProblemData) validDragOperation = true;
+      }
+    }
+
+    protected override void itemsListView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        if (dropData is DataAnalysisProblemData) {
+          DataAnalysisProblemData problemData = (DataAnalysisProblemData)dropData;
+          Content.ProblemData = (DataAnalysisProblemData)problemData.Clone();
+        } else if (dropData is IValueParameter) {
+          var param = (IValueParameter)dropData;
+          DataAnalysisProblemData problemData = param.Value as DataAnalysisProblemData;
+          if (problemData != null)
+            Content.ProblemData = (DataAnalysisProblemData)problemData.Clone();
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class DiscriminantFunctionClassificationSolutionView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/DiscriminantFunctionClassificationSolutionView.cs	(revision 16097)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using HeuristicLab.MainForm;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("ClassificationSolution View")]
+  [Content(typeof(DiscriminantFunctionClassificationSolutionBase), false)]
+  public partial class DiscriminantFunctionClassificationSolutionView : ClassificationSolutionView {
+    public DiscriminantFunctionClassificationSolutionView() {
+      InitializeComponent();
+    }
+
+    public new DiscriminantFunctionClassificationSolutionBase Content {
+      get { return (DiscriminantFunctionClassificationSolutionBase)base.Content; }
+      set { base.Content = value; }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,66 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views.Solution_Views {
+  partial class NamedDataAnalysisSolutionView {
+    /// <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() {
+      this.panel = new System.Windows.Forms.Panel();
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // nameTextBox
+      // 
+      this.errorProvider.SetIconAlignment(this.nameTextBox, System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
+      this.errorProvider.SetIconPadding(this.nameTextBox, 2);
+      // 
+      // panel
+      // 
+      this.panel.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.panel.Location = new System.Drawing.Point(3, 26);
+      this.panel.Name = "panel";
+      this.panel.Size = new System.Drawing.Size(345, 235);
+      this.panel.TabIndex = 3;
+      // 
+      // NamedDataAnalysisSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Controls.Add(this.panel);
+      this.Name = "NamedDataAnalysisSolutionView";
+      this.Size = new System.Drawing.Size(351, 264);
+      this.Controls.SetChildIndex(this.panel, 0);
+      this.Controls.SetChildIndex(this.nameLabel, 0);
+      this.Controls.SetChildIndex(this.nameTextBox, 0);
+      this.Controls.SetChildIndex(this.infoLabel, 0);
+      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.Panel panel;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/NamedDataAnalysisSolutionView.cs	(revision 16097)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.Core.Views;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views.Solution_Views {
+  [View("DataAnalysisSolutionView")]
+  [Content(typeof(DataAnalysisSolution), true)]
+  public partial class NamedDataAnalysisSolutionView : NamedItemView {
+    private Type contentType;
+    private DataAnalysisSolutionView view;
+
+    public NamedDataAnalysisSolutionView() {
+      InitializeComponent();
+    }
+
+    public new DataAnalysisSolution Content {
+      get { return (DataAnalysisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+
+      if (Content == null) {
+        panel.Controls.Clear();
+      } else if (Content.GetType() == contentType && view != null) {
+        view.Content = Content;
+      } else {
+        view = null;
+        contentType = Content.GetType();
+        panel.Controls.Clear();
+        var viewType = MainFormManager.GetViewTypes(Content.GetType(), true).FirstOrDefault(t => typeof(DataAnalysisSolutionView).IsAssignableFrom(t));
+        if (viewType != null) {
+          view = (DataAnalysisSolutionView)MainFormManager.CreateView(viewType);
+          view.Locked = Locked;
+          view.ReadOnly = ReadOnly;
+          view.Dock = DockStyle.Fill;
+          view.Content = Content;
+          panel.Controls.Add(view);
+        }
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionEnsembleSolutionView {
+    /// <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() {
+      components = new System.ComponentModel.Container();
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionEnsembleSolutionView.cs	(revision 16097)
@@ -0,0 +1,61 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("RegressionEnsembleSolution View")]
+  [Content(typeof(RegressionEnsembleSolution), false)]
+  public partial class RegressionEnsembleSolutionView : RegressionSolutionView {
+    public RegressionEnsembleSolutionView() {
+      InitializeComponent();
+    }
+
+    public new RegressionEnsembleSolution Content {
+      get { return (RegressionEnsembleSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      itemsListView.Items.Remove(itemsListView.FindItemWithText("Model: RegressionEnsembleModel"));
+    }
+
+    #region drag & drop
+    protected override void itemsListView_DragDrop(object sender, DragEventArgs e) {
+      if (e.Effect != DragDropEffects.None) {
+        var droppedData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+        if (droppedData is IValueParameter) droppedData = ((IValueParameter)droppedData).Value;
+
+        RegressionEnsembleProblemData ensembleProblemData = droppedData as RegressionEnsembleProblemData;
+        RegressionProblemData problemData = droppedData as RegressionProblemData;
+        if (ensembleProblemData != null) {
+          Content.ProblemData = (RegressionEnsembleProblemData)ensembleProblemData.Clone();
+        } else if (problemData != null) {
+          Content.ProblemData = new RegressionEnsembleProblemData((IRegressionProblemData)problemData.Clone());
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class RegressionSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Regression Solution";
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // RegressionSolutionView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "RegressionSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/RegressionSolutionView.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("RegressionSolution View")]
+  [Content(typeof(RegressionSolutionBase), false)]
+  public partial class RegressionSolutionView : DataAnalysisSolutionView {
+    public RegressionSolutionView() {
+      InitializeComponent();
+    }
+
+    public new RegressionSolutionBase Content {
+      get { return (RegressionSolutionBase)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is RegressionProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is RegressionProblemData) validDragOperation = true;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.Designer.cs	(revision 16097)
@@ -0,0 +1,73 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisSolutionView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing && (components != null)) {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      this.SuspendLayout();
+      // 
+      // itemsGroupBox
+      // 
+      this.itemsGroupBox.Text = "Time-series Prognosis Solution";
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+      this.Name = "RegressionSolutionView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/Solution Views/TimeSeriesPrognosisSolutionView.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.Core;
+using HeuristicLab.MainForm;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("TimeSeriesPrognosisSolution View")]
+  [Content(typeof(TimeSeriesPrognosisSolution), false)]
+  public partial class TimeSeriesPrognosisSolutionView : RegressionSolutionView {
+    public TimeSeriesPrognosisSolutionView() {
+      InitializeComponent();
+    }
+
+    public new TimeSeriesPrognosisSolution Content {
+      get { return (TimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+
+    #region drag and drop
+    protected override void itemsListView_DragEnter(object sender, DragEventArgs e) {
+      validDragOperation = false;
+      if (ReadOnly) return;
+
+      var dropData = e.Data.GetData(HeuristicLab.Common.Constants.DragDropDataFormat);
+      if (dropData is ITimeSeriesPrognosisProblemData) validDragOperation = true;
+      else if (dropData is IValueParameter) {
+        var param = (IValueParameter)dropData;
+        if (param.Value is ITimeSeriesPrognosisProblemData) validDragOperation = true;
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.Designer.cs	(revision 16097)
@@ -0,0 +1,169 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisResultsView {
+    /// <summary> 
+    /// Required designer variable.
+    /// </summary>
+    private System.ComponentModel.IContainer components = null;
+
+    /// <summary> 
+    /// Clean up any resources being used.
+    /// </summary>
+    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+    protected override void Dispose(bool disposing) {
+      if (disposing) {
+        if (components != null) components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
+    #region Component Designer generated code
+
+    /// <summary> 
+    /// Required method for Designer support - do not modify 
+    /// the contents of this method with the code editor.
+    /// </summary>
+    private void InitializeComponent() {
+      this.components = new System.ComponentModel.Container();
+      this.TrainingHorizonLabel = new System.Windows.Forms.Label();
+      this.TestHorizonLabel = new System.Windows.Forms.Label();
+      this.TrainingHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TestHorizonTextBox = new System.Windows.Forms.TextBox();
+      this.TrainingHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      this.TestHorizonErrorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).BeginInit();
+      this.splitContainer.Panel1.SuspendLayout();
+      this.splitContainer.Panel2.SuspendLayout();
+      this.splitContainer.SuspendLayout();
+      this.itemsGroupBox.SuspendLayout();
+      this.detailsGroupBox.SuspendLayout();
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).BeginInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // splitContainer
+      // 
+      // 
+      // splitContainer.Panel1
+      // 
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonTextBox);
+      this.splitContainer.Panel1.Controls.Add(this.TrainingHorizonLabel);
+      this.splitContainer.Panel1.Controls.Add(this.TestHorizonLabel);
+      // 
+      // itemsListView
+      // 
+      this.itemsListView.Location = new System.Drawing.Point(3, 82);
+      this.itemsListView.Size = new System.Drawing.Size(244, 279);
+      // 
+      // addButton
+      // 
+      this.toolTip.SetToolTip(this.addButton, "Add");
+      // 
+      // removeButton
+      // 
+      this.toolTip.SetToolTip(this.removeButton, "Remove");
+      // 
+      // TrainingHorizonLabel
+      // 
+      this.TrainingHorizonLabel.AutoSize = true;
+      this.TrainingHorizonLabel.Location = new System.Drawing.Point(3, 34);
+      this.TrainingHorizonLabel.Name = "TrainingHorizonLabel";
+      this.TrainingHorizonLabel.Size = new System.Drawing.Size(87, 13);
+      this.TrainingHorizonLabel.TabIndex = 7;
+      this.TrainingHorizonLabel.Text = "Training Horizon:";
+      // 
+      // TestHorizonLabel
+      // 
+      this.TestHorizonLabel.AutoSize = true;
+      this.TestHorizonLabel.Location = new System.Drawing.Point(3, 60);
+      this.TestHorizonLabel.Name = "TestHorizonLabel";
+      this.TestHorizonLabel.Size = new System.Drawing.Size(73, 13);
+      this.TestHorizonLabel.TabIndex = 8;
+      this.TestHorizonLabel.Text = "Test Horizon: ";
+      // 
+      // TrainingHorizonTextBox
+      // 
+      this.TrainingHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TrainingHorizonTextBox.Location = new System.Drawing.Point(96, 31);
+      this.TrainingHorizonTextBox.Name = "TrainingHorizonTextBox";
+      this.TrainingHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TrainingHorizonTextBox.TabIndex = 1;
+      this.TrainingHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TrainingHorizonTextBox_KeyDown);
+      this.TrainingHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TrainingHorizonTextBox_Validating);
+      this.TrainingHorizonTextBox.Validated += new System.EventHandler(this.TrainingHorizonTextBox_Validated);
+      // 
+      // TestHorizonTextBox
+      // 
+      this.TestHorizonTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+            | System.Windows.Forms.AnchorStyles.Right)));
+      this.TestHorizonTextBox.Location = new System.Drawing.Point(96, 57);
+      this.TestHorizonTextBox.Name = "TestHorizonTextBox";
+      this.TestHorizonTextBox.Size = new System.Drawing.Size(151, 20);
+      this.TestHorizonTextBox.TabIndex = 1;
+      this.TestHorizonTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TestHorizonTextBox_KeyDown);
+      this.TestHorizonTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.TestHorizonTextBox_Validating);
+      this.TestHorizonTextBox.Validated += new System.EventHandler(this.TestHorizonTextBox_Validated);
+      // 
+      // TrainingHorizonErrorProvider
+      // 
+      this.TrainingHorizonErrorProvider.BlinkRate = 0;
+      this.TrainingHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TrainingHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TestHorizonErrorProvider
+      // 
+      this.TestHorizonErrorProvider.BlinkRate = 0;
+      this.TestHorizonErrorProvider.BlinkStyle = System.Windows.Forms.ErrorBlinkStyle.NeverBlink;
+      this.TestHorizonErrorProvider.ContainerControl = this;
+      // 
+      // TimeSeriesPrognosisResultsView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeSeriesPrognosisResultsView";
+      this.splitContainer.Panel1.ResumeLayout(false);
+      this.splitContainer.Panel1.PerformLayout();
+      this.splitContainer.Panel2.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.splitContainer)).EndInit();
+      this.splitContainer.ResumeLayout(false);
+      this.itemsGroupBox.ResumeLayout(false);
+      this.detailsGroupBox.ResumeLayout(false);
+      ((System.ComponentModel.ISupportInitialize)(this.TrainingHorizonErrorProvider)).EndInit();
+      ((System.ComponentModel.ISupportInitialize)(this.TestHorizonErrorProvider)).EndInit();
+      this.ResumeLayout(false);
+
+    }
+
+    #endregion
+
+    private System.Windows.Forms.TextBox TestHorizonTextBox;
+    private System.Windows.Forms.TextBox TrainingHorizonTextBox;
+    private System.Windows.Forms.Label TrainingHorizonLabel;
+    private System.Windows.Forms.Label TestHorizonLabel;
+    private System.Windows.Forms.ErrorProvider TrainingHorizonErrorProvider;
+    private System.Windows.Forms.ErrorProvider TestHorizonErrorProvider;
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisResultsView.cs	(revision 16097)
@@ -0,0 +1,144 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.Optimization.Views;
+
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("TimeSeriesPrognosisResultsView")]
+  [Content(typeof(TimeSeriesPrognosisResults), IsDefaultView = true)]
+  public partial class TimeSeriesPrognosisResultsView : ResultCollectionView {
+    public new TimeSeriesPrognosisResults Content {
+      get { return (TimeSeriesPrognosisResults)base.Content; }
+      set { base.Content = value; }
+    }
+
+    public override bool Locked {
+      get {
+        return base.Locked;
+      }
+      set {
+        base.Locked = value;
+      }
+    }
+
+    public TimeSeriesPrognosisResultsView() {
+      InitializeComponent();
+      TrainingHorizonErrorProvider.SetIconAlignment(TrainingHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TrainingHorizonErrorProvider.SetIconPadding(TrainingHorizonTextBox, 2);
+      TestHorizonErrorProvider.SetIconAlignment(TestHorizonTextBox, ErrorIconAlignment.MiddleLeft);
+      TestHorizonErrorProvider.SetIconPadding(TestHorizonTextBox, 2);
+    }
+
+    #region Content Events
+    protected override void RegisterContentEvents() {
+      base.RegisterContentEvents();
+      Content.TrainingHorizonChanged += new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged += new System.EventHandler(Content_TestHorizonChanged);
+    }
+    protected override void DeregisterContentEvents() {
+      Content.TrainingHorizonChanged -= new System.EventHandler(Content_TrainingHorizonChanged);
+      Content.TestHorizonChanged -= new System.EventHandler(Content_TestHorizonChanged);
+      base.DeregisterContentEvents();
+    }
+
+    private void Content_TrainingHorizonChanged(object sender, System.EventArgs e) {
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void Content_TestHorizonChanged(object sender, System.EventArgs e) {
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+    #endregion
+
+    protected override void OnContentChanged() {
+      base.OnContentChanged();
+      if (Content == null) {
+        TrainingHorizonTextBox.Text = string.Empty;
+        TestHorizonTextBox.Text = string.Empty;
+      } else {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+      }
+    }
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+      //necessary cause this could be triggered by the base ctor when the controls are not created yet
+      if (TrainingHorizonTextBox == null || TestHorizonTextBox == null) return;
+      TrainingHorizonTextBox.Enabled = Content != null && !Locked;
+      TestHorizonTextBox.Enabled = Content != null && !Locked;
+    }
+
+    #region Control events
+    private void TrainingHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int trainingHorizon;
+      if (!int.TryParse(TrainingHorizonTextBox.Text, out trainingHorizon)) {
+        e.Cancel = true;
+        TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, "Please enter a numeric value.");
+        TrainingHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TrainingHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TrainingHorizon = int.Parse(TrainingHorizonTextBox.Text);
+      TrainingHorizonErrorProvider.SetError(TrainingHorizonTextBox, string.Empty);
+      TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+    }
+
+    private void TrainingHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TrainingHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TrainingHorizonTextBox.Text = Content.TrainingHorizon.ToString();
+        TrainingHorizonLabel.Select();  // select label to validate data
+      }
+    }
+
+    private void TestHorizonTextBox_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
+      int testHorizon;
+      if (!int.TryParse(TestHorizonTextBox.Text, out testHorizon)) {
+        e.Cancel = true;
+        TestHorizonErrorProvider.SetError(TestHorizonTextBox, "Please enter a numeric value.");
+        TestHorizonTextBox.SelectAll();
+      }
+    }
+
+    private void TestHorizonTextBox_Validated(object sender, System.EventArgs e) {
+      Content.TestHorizon = int.Parse(TestHorizonTextBox.Text);
+      TestHorizonErrorProvider.SetError(TestHorizonTextBox, string.Empty);
+      TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+    }
+
+    private void TestHorizonTextBox_KeyDown(object sender, KeyEventArgs e) {
+      if ((e.KeyCode == Keys.Enter) || (e.KeyCode == Keys.Return))
+        TestHorizonLabel.Select();  // select label to validate data
+
+      if (e.KeyCode == Keys.Escape) {
+        TestHorizonTextBox.Text = Content.TestHorizon.ToString();
+        TestHorizonLabel.Select();  // select label to validate data
+      }
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.Designer.cs	(revision 16097)
@@ -0,0 +1,43 @@
+﻿namespace HeuristicLab.Problems.DataAnalysis.Views {
+  partial class TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView {
+    /// <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() {
+      this.components = new System.ComponentModel.Container();
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).BeginInit();
+      this.SuspendLayout();
+      // 
+      // TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView
+      // 
+      this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+      this.Name = "TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView";
+      ((System.ComponentModel.ISupportInitialize)(this.chart)).EndInit();
+      this.ResumeLayout(false);
+      this.PerformLayout();
+
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis.Views/3.4/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView.cs	(revision 16097)
@@ -0,0 +1,63 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Forms;
+using HeuristicLab.MainForm;
+using HeuristicLab.MainForm.WindowsForms;
+namespace HeuristicLab.Problems.DataAnalysis.Views {
+  [View("Error Characteristics Curve")]
+  [Content(typeof(ITimeSeriesPrognosisSolution))]
+  public partial class TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView : RegressionSolutionErrorCharacteristicsCurveView {
+
+
+    public TimeSeriesPrognosisSolutionErrorCharacteristicsCurveView()
+      : base() {
+      InitializeComponent();
+    }
+
+    public new ITimeSeriesPrognosisSolution Content {
+      get { return (ITimeSeriesPrognosisSolution)base.Content; }
+      set { base.Content = value; }
+    }
+    public new ITimeSeriesPrognosisProblemData ProblemData {
+      get {
+        if (Content == null) return null;
+        return Content.ProblemData;
+      }
+    }
+
+    protected override void UpdateChart() {
+      base.UpdateChart();
+      if (Content == null) return;
+
+      //AR1 model
+      double alpha, beta;
+      OnlineCalculatorError errorState;
+      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha).CreateTimeSeriesPrognosisSolution(ProblemData);
+      AR1model.Name = "AR(1) Model";
+      AddRegressionSolution(AR1model);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Dataset.cs	(revision 16097)
@@ -0,0 +1,246 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Dataset", "Represents a dataset containing data that should be analyzed.")]
+  [StorableClass]
+  public sealed class Dataset : NamedItem, IStringConvertibleMatrix {
+    [StorableConstructor]
+    private Dataset(bool deserializing) : base(deserializing) { }
+    private Dataset(Dataset original, Cloner cloner)
+      : base(original, cloner) {
+      variableValues = new Dictionary<string, IList>(original.variableValues);
+      variableNames = new List<string>(original.variableNames);
+      rows = original.rows;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new Dataset(this, cloner); }
+
+    public Dataset()
+      : base() {
+      Name = "-";
+      VariableNames = Enumerable.Empty<string>();
+      variableValues = new Dictionary<string, IList>();
+      rows = 0;
+    }
+
+    public Dataset(IEnumerable<string> variableNames, IEnumerable<IList> variableValues)
+      : base() {
+      Name = "-";
+      if (!variableNames.Any()) {
+        this.variableNames = Enumerable.Range(0, variableValues.Count()).Select(x => "Column " + x).ToList();
+      } else if (variableNames.Count() != variableValues.Count()) {
+        throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
+      } else if (!variableValues.All(list => list.Count == variableValues.First().Count)) {
+        throw new ArgumentException("The number of values must be equal for every variable");
+      } else if (variableNames.Distinct().Count() != variableNames.Count()) {
+        var duplicateVariableNames =
+          variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
+        string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
+        foreach (var duplicateVariableName in duplicateVariableNames)
+          message += duplicateVariableName + Environment.NewLine;
+        throw new ArgumentException(message);
+      }
+
+      rows = variableValues.First().Count;
+      this.variableNames = new List<string>(variableNames);
+      this.variableValues = new Dictionary<string, IList>(this.variableNames.Count);
+      for (int i = 0; i < this.variableNames.Count; i++) {
+        var values = variableValues.ElementAt(i);
+        IList clonedValues = null;
+        if (values is List<double>)
+          clonedValues = new List<double>(values.Cast<double>());
+        else if (values is List<string>)
+          clonedValues = new List<string>(values.Cast<string>());
+        else if (values is List<DateTime>)
+          clonedValues = new List<DateTime>(values.Cast<DateTime>());
+        else {
+          this.variableNames = new List<string>();
+          this.variableValues = new Dictionary<string, IList>();
+          throw new ArgumentException("The variable values must be of type List<double>, List<string> or List<DateTime>");
+        }
+        this.variableValues.Add(this.variableNames[i], clonedValues);
+      }
+    }
+
+    public Dataset(IEnumerable<string> variableNames, double[,] variableValues) {
+      Name = "-";
+      if (variableNames.Count() != variableValues.GetLength(1)) {
+        throw new ArgumentException("Number of variable names doesn't match the number of columns of variableValues");
+      }
+      if (variableNames.Distinct().Count() != variableNames.Count()) {
+        var duplicateVariableNames = variableNames.GroupBy(v => v).Where(g => g.Count() > 1).Select(g => g.Key).ToList();
+        string message = "The dataset cannot contain duplicate variables names: " + Environment.NewLine;
+        foreach (var duplicateVariableName in duplicateVariableNames)
+          message += duplicateVariableName + Environment.NewLine;
+        throw new ArgumentException(message);
+      }
+
+      rows = variableValues.GetLength(0);
+      this.variableNames = new List<string>(variableNames);
+
+      this.variableValues = new Dictionary<string, IList>(variableValues.GetLength(1));
+      for (int col = 0; col < variableValues.GetLength(1); col++) {
+        string columName = this.variableNames[col];
+        var values = new List<double>(variableValues.GetLength(0));
+        for (int row = 0; row < variableValues.GetLength(0); row++) {
+          values.Add(variableValues[row, col]);
+        }
+        this.variableValues.Add(columName, values);
+      }
+    }
+
+    #region Backwards compatible code, remove with 3.5
+    private double[,] storableData;
+    //name alias used to suppport backwards compatibility
+    [Storable(Name = "data", AllowOneWay = true)]
+    private double[,] StorableData { set { storableData = value; } }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (variableValues == null) {
+        rows = storableData.GetLength(0);
+        variableValues = new Dictionary<string, IList>();
+        for (int col = 0; col < storableData.GetLength(1); col++) {
+          string columName = variableNames[col];
+          var values = new List<double>(rows);
+          for (int row = 0; row < rows; row++) {
+            values.Add(storableData[row, col]);
+          }
+          variableValues.Add(columName, values);
+        }
+        storableData = null;
+      }
+    }
+    #endregion
+
+    [Storable(Name = "VariableValues")]
+    private Dictionary<string, IList> variableValues;
+
+    private List<string> variableNames;
+    [Storable]
+    public IEnumerable<string> VariableNames {
+      get { return variableNames; }
+      private set {
+        if (variableNames != null) throw new InvalidOperationException();
+        variableNames = new List<string>(value);
+      }
+    }
+
+    public IEnumerable<string> DoubleVariables {
+      get { return variableValues.Where(p => p.Value is List<double>).Select(p => p.Key); }
+    }
+
+    public IEnumerable<double> GetDoubleValues(string variableName) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<double> values = list as List<double>;
+      if (values == null) throw new ArgumentException("The variable " + variableName + " is not a double variable.");
+
+      //mkommend yield return used to enable lazy evaluation
+      foreach (double value in values)
+        yield return value;
+    }
+    public ReadOnlyCollection<double> GetReadOnlyDoubleValues(string variableName) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<double> values = list as List<double>;
+      if (values == null) throw new ArgumentException("The variable " + variableName + " is not a double variable.");
+      return values.AsReadOnly();
+    }
+    public double GetDoubleValue(string variableName, int row) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<double> values = list as List<double>;
+      if (values == null) throw new ArgumentException("The variable " + variableName + " is not a double variable.");
+      return values[row];
+    }
+    public IEnumerable<double> GetDoubleValues(string variableName, IEnumerable<int> rows) {
+      IList list;
+      if (!variableValues.TryGetValue(variableName, out list))
+        throw new ArgumentException("The variable " + variableName + " does not exist in the dataset.");
+      List<double> values = list as List<double>;
+      if (values == null) throw new ArgumentException("The varialbe " + variableName + " is not a double variable.");
+
+      return rows.Select(index => values[index]);
+    }
+
+    #region IStringConvertibleMatrix Members
+    [Storable]
+    private int rows;
+    public int Rows {
+      get { return rows; }
+      set { throw new NotSupportedException(); }
+    }
+    public int Columns {
+      get { return variableNames.Count; }
+      set { throw new NotSupportedException(); }
+    }
+
+    public bool SortableView {
+      get { return false; }
+      set { throw new NotSupportedException(); }
+    }
+    public bool ReadOnly {
+      get { return true; }
+    }
+
+    IEnumerable<string> IStringConvertibleMatrix.ColumnNames {
+      get { return this.VariableNames; }
+      set { throw new NotSupportedException(); }
+    }
+    IEnumerable<string> IStringConvertibleMatrix.RowNames {
+      get { return Enumerable.Empty<string>(); }
+      set { throw new NotSupportedException(); }
+    }
+
+    public string GetValue(int rowIndex, int columnIndex) {
+      return variableValues[variableNames[columnIndex]][rowIndex].ToString();
+    }
+    public bool SetValue(string value, int rowIndex, int columnIndex) {
+      throw new NotSupportedException();
+    }
+    public bool Validate(string value, out string errorMessage) {
+      throw new NotSupportedException();
+    }
+
+    public event EventHandler ColumnsChanged { add { } remove { } }
+    public event EventHandler RowsChanged { add { } remove { } }
+    public event EventHandler ColumnNamesChanged { add { } remove { } }
+    public event EventHandler RowNamesChanged { add { } remove { } }
+    public event EventHandler SortableViewChanged { add { } remove { } }
+    public event EventHandler<EventArgs<int, int>> ItemChanged { add { } remove { } }
+    public event EventHandler Reset { add { } remove { } }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DatasetExtensions.cs	(revision 16097)
@@ -0,0 +1,34 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public static class DatasetExtensions {
+    public static IEnumerable<T> TakeEvery<T>(this IEnumerable<T> xs, int nth) {
+      int i = 0;
+      foreach (var x in xs) {
+        if (i % nth == 0) yield return x;
+        i++;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/DoubleLimit.cs	(revision 16097)
@@ -0,0 +1,66 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("DoubleLimit", "Represents a lower and a upper bound for double values.")]
+  public class DoubleLimit : StringConvertibleValueTuple<DoubleValue, DoubleValue> {
+
+    public double Lower {
+      get { return Item1.Value; }
+      set { Item1.Value = value; }
+    }
+    public double Upper {
+      get { return Item2.Value; }
+      set { Item2.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected DoubleLimit(bool deserializing) : base(deserializing) { }
+    protected DoubleLimit(DoubleLimit original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DoubleLimit(this, cloner);
+    }
+
+    public DoubleLimit() : base(new DoubleValue(), new DoubleValue()) { }
+    public DoubleLimit(DoubleValue start, DoubleValue end) : base(start, end) { }
+    public DoubleLimit(double start, double end) : base(new DoubleValue(start), new DoubleValue(end)) { }
+
+    public override string ToString() {
+      return string.Format("Lower: {0}, Upper: {1}", Lower, Upper);
+    }
+
+    public override StringConvertibleValueTuple<DoubleValue, DoubleValue> AsReadOnly() {
+      var readOnly = new DoubleLimit();
+      readOnly.values = Tuple.Create<DoubleValue, DoubleValue>((DoubleValue)Item1.AsReadOnly(), (DoubleValue)Item2.AsReadOnly());
+      readOnly.readOnly = true;
+      return readOnly;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/HeuristicLab.Problems.DataAnalysis-3.4.csproj	(revision 16097)
@@ -0,0 +1,312 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.30729</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Problems.DataAnalysis</RootNamespace>
+    <AssemblyName>HeuristicLab.Problems.DataAnalysis-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <SignAssembly>true</SignAssembly>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <FileUpgradeFlags>
+    </FileUpgradeFlags>
+    <OldToolsVersion>3.5</OldToolsVersion>
+    <UpgradeBackupLocation />
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <OutputPath>$(SolutionDir)\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>&gt;..\..\..\..\trunk\sources\bin\ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.ALGLIB-3.6.0, Version=3.6.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <HintPath>&gt;..\..\..\..\trunk\sources\bin\HeuristicLab.ALGLIB-3.6.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Xml.Linq">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data.DataSetExtensions">
+      <RequiredTargetFramework>3.5</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="DatasetExtensions.cs" />
+    <Compile Include="DoubleLimit.cs" />
+    <Compile Include="Implementation\Classification\ClassificationEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Implementation\Classification\ClassificationEnsembleSolution.cs" />
+    <Compile Include="Implementation\Classification\ClassificationProblemData.cs" />
+    <Compile Include="Implementation\Classification\ClassificationProblem.cs" />
+    <Compile Include="Implementation\Classification\ClassificationSolution.cs" />
+    <Compile Include="Implementation\Classification\ClassificationEnsembleProblemData.cs" />
+    <Compile Include="Implementation\Classification\ClassificationSolutionBase.cs" />
+    <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolutionBase.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\AverageThresholdCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\AverageThresholdClassificationCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\MedianThresholdClassificationCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\DiscriminantClassificationWeightCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\MedianThresholdCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\MajorityVoteWeightCalculator.cs" />
+    <Compile Include="Implementation\Classification\WeightCalculators\ClassificationWeightCalculator.cs" />
+    <Compile Include="Implementation\Clustering\ClusteringProblem.cs" />
+    <Compile Include="Implementation\Clustering\ClusteringProblemData.cs" />
+    <Compile Include="Implementation\Clustering\ClusteringSolution.cs" />
+    <Compile Include="Implementation\Regression\ConstantRegressionModel.cs" />
+    <Compile Include="Implementation\Regression\ConstantRegressionSolution.cs" />
+    <Compile Include="Implementation\Regression\RegressionEnsembleProblemData.cs" />
+    <Compile Include="Implementation\Regression\RegressionEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Implementation\Regression\RegressionEnsembleSolution.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\ConstantTimeSeriesPrognosisModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\Models\TimeSeriesPrognosisAutoRegressiveModel.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblem.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisProblemData.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisResults.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolution.cs" />
+    <Compile Include="Implementation\TimeSeriesPrognosis\TimeSeriesPrognosisSolutionBase.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Interfaces\Classification\IClassificationEnsembleSolution.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Interfaces\Classification\IClassificationEnsembleSolutionWeightCalculator.cs" />
+    <Compile Include="Interfaces\Classification\IDiscriminantFunctionThresholdCalculator.cs" />
+    <Compile Include="Interfaces\IDependencyCalculator.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionEnsembleModel.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Interfaces\Regression\IRegressionEnsembleSolution.cs" />
+    <Compile Include="Implementation\Regression\RegressionSolutionBase.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\IOnlineTimeSeriesCalculator.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisModel.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblem.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisProblemData.cs" />
+    <Compile Include="Interfaces\TimeSeriesPrognosis\ITimeSeriesPrognosisSolution.cs" />
+    <Compile Include="OnlineCalculators\AutoCorrelationCalculator.cs" />
+    <Compile Include="OnlineCalculators\DependencyCalculator\HoeffdingsDependenceCalculator.cs" />
+    <Compile Include="OnlineCalculators\DependencyCalculator\PearsonsRDependenceCalculator.cs" />
+    <Compile Include="OnlineCalculators\DependencyCalculator\PearsonsRSquaredDependenceCalculator.cs" />
+    <Compile Include="OnlineCalculators\DependencyCalculator\SpearmansRankCorrelationCoefficientCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineBoundedMeanSquaredErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineDirectionalSymmetryCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineMaxAbsoluteErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\NormalizedGiniCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanAbsoluteErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineLinearScalingParameterCalculator.cs" />
+    <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationModel.cs" />
+    <Compile Include="Implementation\Classification\DiscriminantFunctionClassificationSolution.cs" />
+    <Compile Include="Implementation\DataAnalysisSolution.cs" />
+    <Compile Include="Interfaces\Classification\IDiscriminantFunctionClassificationModel.cs" />
+    <Compile Include="Interfaces\Classification\IDiscriminantFunctionClassificationSolution.cs" />
+    <Compile Include="Interfaces\Clustering\IClusteringModel.cs" />
+    <Compile Include="Interfaces\Clustering\IClusteringProblem.cs" />
+    <Compile Include="Interfaces\Clustering\IClusteringProblemData.cs" />
+    <Compile Include="Interfaces\Clustering\IClusteringSolution.cs" />
+    <Compile Include="OnlineCalculators\OnlineAccuracyCalculator.cs" />
+    <Compile Include="Implementation\Regression\RegressionProblemData.cs" />
+    <Compile Include="Implementation\DataAnalysisProblemData.cs" />
+    <Compile Include="Implementation\Regression\RegressionProblem.cs" />
+    <Compile Include="Implementation\DataAnalysisProblem.cs" />
+    <Compile Include="Dataset.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationModel.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationProblem.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationProblemData.cs" />
+    <Compile Include="Interfaces\Classification\IClassificationSolution.cs" />
+    <Compile Include="Interfaces\IDataAnalysisProblemData.cs" />
+    <Compile Include="Interfaces\IDataAnalysisSolution.cs" />
+    <Compile Include="Interfaces\IOnlineCalculator.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionModel.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionProblem.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionProblemData.cs" />
+    <Compile Include="Interfaces\Regression\IRegressionSolution.cs" />
+    <Compile Include="OnlineCalculators\OnlineCovarianceCalcualtor.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanAbsolutePercentageErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanAndVarianceCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineMeanSquaredErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineNormalizedMeanSquaredErrorCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlinePearsonsRSquaredCalculator.cs" />
+    <Compile Include="Implementation\Regression\RegressionSolution.cs" />
+    <Compile Include="OnlineCalculators\OnlineTheilsUStatisticCalculator.cs" />
+    <Compile Include="OnlineCalculators\OnlineWeightedDirectionalSymmetryCalculator.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Implementation\Classification\ThresholdCalculators\AccuracyMaximizationThresholdCalculator.cs" />
+    <Compile Include="Implementation\Classification\ThresholdCalculators\NormalDistributionCutPointsThresholdCalculator.cs" />
+    <Compile Include="Implementation\Classification\ThresholdCalculators\ThresholdCalculator.cs" />
+    <None Include="HeuristicLab.snk" />
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Interfaces\IDataAnalysisModel.cs" />
+    <Compile Include="Interfaces\IDataAnalysisProblem.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 3.1</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <ItemGroup />
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+  <PropertyGroup>
+    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+export ProjectDir=$(ProjectDir)
+export SolutionDir=$(SolutionDir)
+
+$SolutionDir/PreBuildEvent.sh
+</PreBuildEvent>
+  </PropertyGroup>
+</Project>
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleModel.cs	(revision 16097)
@@ -0,0 +1,101 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents classification solutions that contain an ensemble of multiple classification models
+  /// </summary>
+  [StorableClass]
+  [Item("ClassificationEnsembleModel", "A classification model that contains an ensemble of multiple classification models")]
+  public class ClassificationEnsembleModel : NamedItem, IClassificationEnsembleModel {
+
+    [Storable]
+    private List<IClassificationModel> models;
+    public IEnumerable<IClassificationModel> Models {
+      get { return new List<IClassificationModel>(models); }
+    }
+
+    [StorableConstructor]
+    protected ClassificationEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleModel(ClassificationEnsembleModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
+    }
+
+    public ClassificationEnsembleModel() : this(Enumerable.Empty<IClassificationModel>()) { }
+    public ClassificationEnsembleModel(IEnumerable<IClassificationModel> models)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.models = new List<IClassificationModel>(models);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationEnsembleModel(this, cloner);
+    }
+
+    #region IClassificationEnsembleModel Members
+    public void Add(IClassificationModel model) {
+      models.Add(model);
+    }
+    public void Remove(IClassificationModel model) {
+      models.Remove(model);
+    }
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    #endregion
+
+    #region IClassificationModel Members
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var estimatedValuesVector in GetEstimatedClassValueVectors(dataset, rows)) {
+        // return the class which is most often occuring
+        yield return
+          estimatedValuesVector
+          .GroupBy(x => x)
+          .OrderBy(g => -g.Count())
+          .Select(g => g.Key)
+          .First();
+      }
+    }
+
+    IClassificationSolution IClassificationModel.CreateClassificationSolution(IClassificationProblemData problemData) {
+      return new ClassificationEnsembleSolution(models, new ClassificationEnsembleProblemData(problemData));
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleProblemData.cs	(revision 16097)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClassificationEnsembleProblemData", "Represents an item containing all data defining a classification problem.")]
+  public class ClassificationEnsembleProblemData : ClassificationProblemData {
+
+    public override bool IsTrainingSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+             TrainingPartition.Start <= index && index < TrainingPartition.End;
+    }
+
+    public override bool IsTestSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+             TestPartition.Start <= index && index < TestPartition.End;
+    }
+
+    private static readonly ClassificationEnsembleProblemData emptyProblemData;
+    public static new ClassificationEnsembleProblemData EmptyProblemData {
+      get { return emptyProblemData; }
+    }
+
+    static ClassificationEnsembleProblemData() {
+      var problemData = new ClassificationEnsembleProblemData();
+      problemData.Parameters.Clear();
+      problemData.Name = "Empty Classification ProblemData";
+      problemData.Description = "This ProblemData acts as place holder before the correct problem data is loaded.";
+      problemData.isEmpty = true;
+
+      problemData.Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", new Dataset()));
+      problemData.Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, ""));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
+      problemData.Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, "", new StringMatrix(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, "", (DoubleMatrix)new DoubleMatrix(0, 0).AsReadOnly()));
+      emptyProblemData = problemData;
+    }
+
+    [StorableConstructor]
+    protected ClassificationEnsembleProblemData(bool deserializing) : base(deserializing) { }
+    protected ClassificationEnsembleProblemData(ClassificationEnsembleProblemData original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (this == emptyProblemData) return emptyProblemData;
+      return new ClassificationEnsembleProblemData(this, cloner);
+    }
+
+    public ClassificationEnsembleProblemData() : base() { }
+    public ClassificationEnsembleProblemData(IClassificationProblemData classificationProblemData)
+      : base(classificationProblemData.Dataset, classificationProblemData.AllowedInputVariables, classificationProblemData.TargetVariable) {
+      this.TrainingPartition.Start = classificationProblemData.TrainingPartition.Start;
+      this.TrainingPartition.End = classificationProblemData.TrainingPartition.End;
+      this.TestPartition.Start = classificationProblemData.TestPartition.Start;
+      this.TestPartition.End = classificationProblemData.TestPartition.End;
+    }
+
+    public ClassificationEnsembleProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables, targetVariable) {
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationEnsembleSolution.cs	(revision 16097)
@@ -0,0 +1,282 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents classification solutions that contain an ensemble of multiple classification models
+  /// </summary>
+  [StorableClass]
+  [Item("Classification Ensemble Solution", "A classification solution that contains an ensemble of multiple classification models")]
+  [Creatable("Data Analysis - Ensembles")]
+  public sealed class ClassificationEnsembleSolution : ClassificationSolutionBase, IClassificationEnsembleSolution {
+    private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> evaluationCache = new Dictionary<int, double>();
+
+    public new IClassificationEnsembleModel Model {
+      get { return (IClassificationEnsembleModel)base.Model; }
+    }
+    public new ClassificationEnsembleProblemData ProblemData {
+      get { return (ClassificationEnsembleProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    private readonly CheckedItemCollection<IClassificationSolution> classificationSolutions;
+    public ICheckedItemCollection<IClassificationSolution> ClassificationSolutions {
+      get { return classificationSolutions; }
+    }
+
+    private IClassificationEnsembleSolutionWeightCalculator weightCalculator;
+    public IClassificationEnsembleSolutionWeightCalculator WeightCalculator {
+      set {
+        if (value != null) {
+          weightCalculator = value;
+          if (!ProblemData.IsEmpty) {
+            RecalculateResults();
+          }
+        }
+      }
+      get { return weightCalculator; }
+    }
+
+    [Storable]
+    private Dictionary<IClassificationModel, IntRange> trainingPartitions;
+    [Storable]
+    private Dictionary<IClassificationModel, IntRange> testPartitions;
+
+    [StorableConstructor]
+    private ClassificationEnsembleSolution(bool deserializing)
+      : base(deserializing) {
+      classificationSolutions = new CheckedItemCollection<IClassificationSolution>();
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      foreach (var model in Model.Models) {
+        IClassificationProblemData problemData = (IClassificationProblemData)ProblemData.Clone();
+        problemData.TrainingPartition.Start = trainingPartitions[model].Start;
+        problemData.TrainingPartition.End = trainingPartitions[model].End;
+        problemData.TestPartition.Start = testPartitions[model].Start;
+        problemData.TestPartition.End = testPartitions[model].End;
+
+        classificationSolutions.Add(model.CreateClassificationSolution(problemData));
+      }
+      RegisterClassificationSolutionsEventHandler();
+    }
+
+    private ClassificationEnsembleSolution(ClassificationEnsembleSolution original, Cloner cloner)
+      : base(original, cloner) {
+      trainingPartitions = new Dictionary<IClassificationModel, IntRange>();
+      testPartitions = new Dictionary<IClassificationModel, IntRange>();
+      foreach (var pair in original.trainingPartitions) {
+        trainingPartitions[cloner.Clone(pair.Key)] = cloner.Clone(pair.Value);
+      }
+      foreach (var pair in original.testPartitions) {
+        testPartitions[cloner.Clone(pair.Key)] = cloner.Clone(pair.Value);
+      }
+
+      weightCalculator = cloner.Clone(original.weightCalculator);
+      classificationSolutions = cloner.Clone(original.classificationSolutions);
+      RegisterClassificationSolutionsEventHandler();
+    }
+
+    public ClassificationEnsembleSolution()
+      : base(new ClassificationEnsembleModel(), ClassificationEnsembleProblemData.EmptyProblemData) {
+      trainingPartitions = new Dictionary<IClassificationModel, IntRange>();
+      testPartitions = new Dictionary<IClassificationModel, IntRange>();
+      classificationSolutions = new CheckedItemCollection<IClassificationSolution>();
+      weightCalculator = new MajorityVoteWeightCalculator();
+
+      RegisterClassificationSolutionsEventHandler();
+    }
+
+    public ClassificationEnsembleSolution(IClassificationProblemData problemData) :
+      this(Enumerable.Empty<IClassificationModel>(), problemData) { }
+
+    public ClassificationEnsembleSolution(IEnumerable<IClassificationModel> models, IClassificationProblemData problemData)
+      : this(models, problemData,
+             models.Select(m => (IntRange)problemData.TrainingPartition.Clone()),
+             models.Select(m => (IntRange)problemData.TestPartition.Clone())
+      ) { }
+
+    public ClassificationEnsembleSolution(IEnumerable<IClassificationModel> models, IClassificationProblemData problemData, IEnumerable<IntRange> trainingPartitions, IEnumerable<IntRange> testPartitions)
+      : base(new ClassificationEnsembleModel(Enumerable.Empty<IClassificationModel>()), new ClassificationEnsembleProblemData(problemData)) {
+      this.trainingPartitions = new Dictionary<IClassificationModel, IntRange>();
+      this.testPartitions = new Dictionary<IClassificationModel, IntRange>();
+      this.classificationSolutions = new CheckedItemCollection<IClassificationSolution>();
+
+      List<IClassificationSolution> solutions = new List<IClassificationSolution>();
+      var modelEnumerator = models.GetEnumerator();
+      var trainingPartitionEnumerator = trainingPartitions.GetEnumerator();
+      var testPartitionEnumerator = testPartitions.GetEnumerator();
+
+      while (modelEnumerator.MoveNext() & trainingPartitionEnumerator.MoveNext() & testPartitionEnumerator.MoveNext()) {
+        IClassificationProblemData p = (IClassificationProblemData)ProblemData.Clone();
+        p.TrainingPartition.Start = trainingPartitionEnumerator.Current.Start;
+        p.TrainingPartition.End = trainingPartitionEnumerator.Current.End;
+        p.TestPartition.Start = testPartitionEnumerator.Current.Start;
+        p.TestPartition.End = testPartitionEnumerator.Current.End;
+
+        solutions.Add(modelEnumerator.Current.CreateClassificationSolution(p));
+      }
+      if (modelEnumerator.MoveNext() | trainingPartitionEnumerator.MoveNext() | testPartitionEnumerator.MoveNext()) {
+        throw new ArgumentException();
+      }
+
+      RegisterClassificationSolutionsEventHandler();
+      weightCalculator = new MajorityVoteWeightCalculator();
+      classificationSolutions.AddRange(solutions);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClassificationEnsembleSolution(this, cloner);
+    }
+    private void RegisterClassificationSolutionsEventHandler() {
+      classificationSolutions.ItemsAdded += new CollectionItemsChangedEventHandler<IClassificationSolution>(classificationSolutions_ItemsAdded);
+      classificationSolutions.ItemsRemoved += new CollectionItemsChangedEventHandler<IClassificationSolution>(classificationSolutions_ItemsRemoved);
+      classificationSolutions.CollectionReset += new CollectionItemsChangedEventHandler<IClassificationSolution>(classificationSolutions_CollectionReset);
+      classificationSolutions.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IClassificationSolution>(classificationSolutions_CheckedItemsChanged);
+    }
+
+
+    #region Evaluation
+    public override IEnumerable<double> EstimatedClassValues {
+      get { return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+
+    public override IEnumerable<double> EstimatedTrainingClassValues {
+      get {
+        return weightCalculator.AggregateEstimatedClassValues(classificationSolutions.CheckedItems,
+                                                              ProblemData.Dataset,
+                                                              ProblemData.TrainingIndices,
+                                                              weightCalculator.GetTrainingClassDelegate());
+      }
+    }
+
+    public override IEnumerable<double> EstimatedTestClassValues {
+      get {
+        return weightCalculator.AggregateEstimatedClassValues(classificationSolutions.CheckedItems,
+                                                              ProblemData.Dataset,
+                                                              ProblemData.TestIndices,
+                                                              weightCalculator.GetTestClassDelegate());
+      }
+    }
+
+    public override IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
+      return weightCalculator.AggregateEstimatedClassValues(classificationSolutions.CheckedItems,
+                                                            ProblemData.Dataset,
+                                                            rows,
+                                                            weightCalculator.GetAllClassDelegate());
+    }
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      IEnumerable<IClassificationModel> models = classificationSolutions.CheckedItems.Select(sol => sol.Model);
+      if (!models.Any()) yield break;
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedClassValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+    #endregion
+
+    protected override void OnProblemDataChanged() {
+      IClassificationProblemData problemData = new ClassificationProblemData(ProblemData.Dataset,
+                                                                     ProblemData.AllowedInputVariables,
+                                                                     ProblemData.TargetVariable);
+      problemData.TrainingPartition.Start = ProblemData.TrainingPartition.Start;
+      problemData.TrainingPartition.End = ProblemData.TrainingPartition.End;
+      problemData.TestPartition.Start = ProblemData.TestPartition.Start;
+      problemData.TestPartition.End = ProblemData.TestPartition.End;
+
+      foreach (var solution in ClassificationSolutions) {
+        if (solution is ClassificationEnsembleSolution)
+          solution.ProblemData = ProblemData;
+        else
+          solution.ProblemData = problemData;
+      }
+      foreach (var trainingPartition in trainingPartitions.Values) {
+        trainingPartition.Start = ProblemData.TrainingPartition.Start;
+        trainingPartition.End = ProblemData.TrainingPartition.End;
+      }
+      foreach (var testPartition in testPartitions.Values) {
+        testPartition.Start = ProblemData.TestPartition.Start;
+        testPartition.End = ProblemData.TestPartition.End;
+      }
+
+      base.OnProblemDataChanged();
+    }
+
+    public void AddClassificationSolutions(IEnumerable<IClassificationSolution> solutions) {
+      classificationSolutions.AddRange(solutions);
+    }
+    public void RemoveClassificationSolutions(IEnumerable<IClassificationSolution> solutions) {
+      classificationSolutions.RemoveRange(solutions);
+    }
+
+    private void classificationSolutions_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IClassificationSolution> e) {
+      foreach (var solution in e.Items) AddClassificationSolution(solution);
+      RecalculateResults();
+    }
+    private void classificationSolutions_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IClassificationSolution> e) {
+      foreach (var solution in e.Items) RemoveClassificationSolution(solution);
+      RecalculateResults();
+    }
+    private void classificationSolutions_CollectionReset(object sender, CollectionItemsChangedEventArgs<IClassificationSolution> e) {
+      foreach (var solution in e.OldItems) RemoveClassificationSolution(solution);
+      foreach (var solution in e.Items) AddClassificationSolution(solution);
+      RecalculateResults();
+    }
+    private void classificationSolutions_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IClassificationSolution> e) {
+      RecalculateResults();
+    }
+
+    protected override void RecalculateResults() {
+      weightCalculator.CalculateNormalizedWeights(classificationSolutions.CheckedItems);
+      base.RecalculateResults();
+    }
+
+    private void AddClassificationSolution(IClassificationSolution solution) {
+      if (Model.Models.Contains(solution.Model)) throw new ArgumentException();
+      Model.Add(solution.Model);
+      trainingPartitions[solution.Model] = solution.ProblemData.TrainingPartition;
+      testPartitions[solution.Model] = solution.ProblemData.TestPartition;
+    }
+
+    private void RemoveClassificationSolution(IClassificationSolution solution) {
+      if (!Model.Models.Contains(solution.Model)) throw new ArgumentException();
+      Model.Remove(solution.Model);
+      trainingPartitions.Remove(solution.Model);
+      testPartitions.Remove(solution.Model);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblem.cs	(revision 16097)
@@ -0,0 +1,43 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Classification Problem", "A general classification problem.")]
+  [Creatable("Problems")]
+  public class ClassificationProblem : DataAnalysisProblem<IClassificationProblemData>, IClassificationProblem, IStorableContent {
+    public string Filename { get; set; }
+
+    [StorableConstructor]
+    protected ClassificationProblem(bool deserializing) : base(deserializing) { }
+    protected ClassificationProblem(ClassificationProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClassificationProblem(this, cloner); }
+
+    public ClassificationProblem()
+      : base() {
+      ProblemData = new ClassificationProblemData();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationProblemData.cs	(revision 16097)
@@ -0,0 +1,411 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClassificationProblemData", "Represents an item containing all data defining a classification problem.")]
+  public class ClassificationProblemData : DataAnalysisProblemData, IClassificationProblemData, IStorableContent {
+    protected const string TargetVariableParameterName = "TargetVariable";
+    protected const string ClassNamesParameterName = "ClassNames";
+    protected const string ClassificationPenaltiesParameterName = "ClassificationPenalties";
+    protected const int MaximumNumberOfClasses = 100;
+    protected const int InspectedRowsToDetermineTargets = 2000;
+
+    public string Filename { get; set; }
+
+    #region default data
+    private static string[] defaultVariableNames = new string[] { "sample", "clump thickness", "cell size", "cell shape", "marginal adhesion", "epithelial cell size", "bare nuclei", "chromatin", "nucleoli", "mitoses", "class" };
+    private static double[,] defaultData = new double[,]{
+     {1000025,5,1,1,1,2,1,3,1,1,2      },
+     {1002945,5,4,4,5,7,10,3,2,1,2     },
+     {1015425,3,1,1,1,2,2,3,1,1,2      },
+     {1016277,6,8,8,1,3,4,3,7,1,2      },
+     {1017023,4,1,1,3,2,1,3,1,1,2      },
+     {1017122,8,10,10,8,7,10,9,7,1,4   },
+     {1018099,1,1,1,1,2,10,3,1,1,2     },
+     {1018561,2,1,2,1,2,1,3,1,1,2      },
+     {1033078,2,1,1,1,2,1,1,1,5,2      },
+     {1033078,4,2,1,1,2,1,2,1,1,2      },
+     {1035283,1,1,1,1,1,1,3,1,1,2      },
+     {1036172,2,1,1,1,2,1,2,1,1,2      },
+     {1041801,5,3,3,3,2,3,4,4,1,4      },
+     {1043999,1,1,1,1,2,3,3,1,1,2      },
+     {1044572,8,7,5,10,7,9,5,5,4,4     },
+     {1047630,7,4,6,4,6,1,4,3,1,4      },
+     {1048672,4,1,1,1,2,1,2,1,1,2      },
+     {1049815,4,1,1,1,2,1,3,1,1,2      },
+     {1050670,10,7,7,6,4,10,4,1,2,4    },
+     {1050718,6,1,1,1,2,1,3,1,1,2      },
+     {1054590,7,3,2,10,5,10,5,4,4,4    },
+     {1054593,10,5,5,3,6,7,7,10,1,4    },
+     {1056784,3,1,1,1,2,1,2,1,1,2      },
+     {1057013,8,4,5,1,2,2,7,3,1,4      },
+     {1059552,1,1,1,1,2,1,3,1,1,2      },
+     {1065726,5,2,3,4,2,7,3,6,1,4      },
+     {1066373,3,2,1,1,1,1,2,1,1,2      },
+     {1066979,5,1,1,1,2,1,2,1,1,2      },
+     {1067444,2,1,1,1,2,1,2,1,1,2      },
+     {1070935,1,1,3,1,2,1,1,1,1,2      },
+     {1070935,3,1,1,1,1,1,2,1,1,2      },
+     {1071760,2,1,1,1,2,1,3,1,1,2      },
+     {1072179,10,7,7,3,8,5,7,4,3,4     },
+     {1074610,2,1,1,2,2,1,3,1,1,2      },
+     {1075123,3,1,2,1,2,1,2,1,1,2      },
+     {1079304,2,1,1,1,2,1,2,1,1,2      },
+     {1080185,10,10,10,8,6,1,8,9,1,4   },
+     {1081791,6,2,1,1,1,1,7,1,1,2      },
+     {1084584,5,4,4,9,2,10,5,6,1,4     },
+     {1091262,2,5,3,3,6,7,7,5,1,4      },
+     {1096800,6,6,6,9,6,4,7,8,1,2      },
+     {1099510,10,4,3,1,3,3,6,5,2,4     },
+     {1100524,6,10,10,2,8,10,7,3,3,4   },
+     {1102573,5,6,5,6,10,1,3,1,1,4     },
+     {1103608,10,10,10,4,8,1,8,10,1,4  },
+     {1103722,1,1,1,1,2,1,2,1,2,2      },
+     {1105257,3,7,7,4,4,9,4,8,1,4      },
+     {1105524,1,1,1,1,2,1,2,1,1,2      },
+     {1106095,4,1,1,3,2,1,3,1,1,2      },
+     {1106829,7,8,7,2,4,8,3,8,2,4      },
+     {1108370,9,5,8,1,2,3,2,1,5,4      },
+     {1108449,5,3,3,4,2,4,3,4,1,4      },
+     {1110102,10,3,6,2,3,5,4,10,2,4    },
+     {1110503,5,5,5,8,10,8,7,3,7,4     },
+     {1110524,10,5,5,6,8,8,7,1,1,4     },
+     {1111249,10,6,6,3,4,5,3,6,1,4     },
+     {1112209,8,10,10,1,3,6,3,9,1,4    },
+     {1113038,8,2,4,1,5,1,5,4,4,4      },
+     {1113483,5,2,3,1,6,10,5,1,1,4     },
+     {1113906,9,5,5,2,2,2,5,1,1,4      },
+     {1115282,5,3,5,5,3,3,4,10,1,4     },
+     {1115293,1,1,1,1,2,2,2,1,1,2      },
+     {1116116,9,10,10,1,10,8,3,3,1,4   },
+     {1116132,6,3,4,1,5,2,3,9,1,4      },
+     {1116192,1,1,1,1,2,1,2,1,1,2      },
+     {1116998,10,4,2,1,3,2,4,3,10,4    },
+     {1117152,4,1,1,1,2,1,3,1,1,2      },
+     {1118039,5,3,4,1,8,10,4,9,1,4     },
+     {1120559,8,3,8,3,4,9,8,9,8,4      },
+     {1121732,1,1,1,1,2,1,3,2,1,2      },
+     {1121919,5,1,3,1,2,1,2,1,1,2      },
+     {1123061,6,10,2,8,10,2,7,8,10,4   },
+     {1124651,1,3,3,2,2,1,7,2,1,2      },
+     {1125035,9,4,5,10,6,10,4,8,1,4    },
+     {1126417,10,6,4,1,3,4,3,2,3,4     },
+     {1131294,1,1,2,1,2,2,4,2,1,2      },
+     {1132347,1,1,4,1,2,1,2,1,1,2      },
+     {1133041,5,3,1,2,2,1,2,1,1,2      },
+     {1133136,3,1,1,1,2,3,3,1,1,2      },
+     {1136142,2,1,1,1,3,1,2,1,1,2      },
+     {1137156,2,2,2,1,1,1,7,1,1,2      },
+     {1143978,4,1,1,2,2,1,2,1,1,2      },
+     {1143978,5,2,1,1,2,1,3,1,1,2      },
+     {1147044,3,1,1,1,2,2,7,1,1,2      },
+     {1147699,3,5,7,8,8,9,7,10,7,4     },
+     {1147748,5,10,6,1,10,4,4,10,10,4  },
+     {1148278,3,3,6,4,5,8,4,4,1,4      },
+     {1148873,3,6,6,6,5,10,6,8,3,4     },
+     {1152331,4,1,1,1,2,1,3,1,1,2      },
+     {1155546,2,1,1,2,3,1,2,1,1,2      },
+     {1156272,1,1,1,1,2,1,3,1,1,2      },
+     {1156948,3,1,1,2,2,1,1,1,1,2      },
+     {1157734,4,1,1,1,2,1,3,1,1,2      },
+     {1158247,1,1,1,1,2,1,2,1,1,2      },
+     {1160476,2,1,1,1,2,1,3,1,1,2      },
+     {1164066,1,1,1,1,2,1,3,1,1,2      },
+     {1165297,2,1,1,2,2,1,1,1,1,2      },
+     {1165790,5,1,1,1,2,1,3,1,1,2      },
+     {1165926,9,6,9,2,10,6,2,9,10,4    },
+     {1166630,7,5,6,10,5,10,7,9,4,4    },
+     {1166654,10,3,5,1,10,5,3,10,2,4   },
+     {1167439,2,3,4,4,2,5,2,5,1,4      },
+     {1167471,4,1,2,1,2,1,3,1,1,2      },
+     {1168359,8,2,3,1,6,3,7,1,1,4      },
+     {1168736,10,10,10,10,10,1,8,8,8,4 },
+     {1169049,7,3,4,4,3,3,3,2,7,4      },
+     {1170419,10,10,10,8,2,10,4,1,1,4  },
+     {1170420,1,6,8,10,8,10,5,7,1,4    },
+     {1171710,1,1,1,1,2,1,2,3,1,2      },
+     {1171710,6,5,4,4,3,9,7,8,3,4      },
+     {1171795,1,3,1,2,2,2,5,3,2,2      },
+     {1171845,8,6,4,3,5,9,3,1,1,4      },
+     {1172152,10,3,3,10,2,10,7,3,3,4   },
+     {1173216,10,10,10,3,10,8,8,1,1,4  },
+     {1173235,3,3,2,1,2,3,3,1,1,2      },
+     {1173347,1,1,1,1,2,5,1,1,1,2      },
+     {1173347,8,3,3,1,2,2,3,2,1,2      },
+     {1173509,4,5,5,10,4,10,7,5,8,4    },
+     {1173514,1,1,1,1,4,3,1,1,1,2      },
+     {1173681,3,2,1,1,2,2,3,1,1,2      },
+     {1174057,1,1,2,2,2,1,3,1,1,2      },
+     {1174057,4,2,1,1,2,2,3,1,1,2      },
+     {1174131,10,10,10,2,10,10,5,3,3,4 },
+     {1174428,5,3,5,1,8,10,5,3,1,4     },
+     {1175937,5,4,6,7,9,7,8,10,1,4     },
+     {1176406,1,1,1,1,2,1,2,1,1,2      },
+     {1176881,7,5,3,7,4,10,7,5,5,4        }
+};
+    private static readonly Dataset defaultDataset;
+    private static readonly IEnumerable<string> defaultAllowedInputVariables;
+    private static readonly string defaultTargetVariable;
+
+    private static readonly ClassificationProblemData emptyProblemData;
+    public static ClassificationProblemData EmptyProblemData {
+      get { return EmptyProblemData; }
+    }
+
+    static ClassificationProblemData() {
+      defaultDataset = new Dataset(defaultVariableNames, defaultData);
+      defaultDataset.Name = "Wisconsin classification problem";
+      defaultDataset.Description = "subset from to ..";
+
+      defaultAllowedInputVariables = defaultVariableNames.Except(new List<string>() { "sample", "class" });
+      defaultTargetVariable = "class";
+
+      var problemData = new ClassificationProblemData();
+      problemData.Parameters.Clear();
+      problemData.Name = "Empty Classification ProblemData";
+      problemData.Description = "This ProblemData acts as place holder before the correct problem data is loaded.";
+      problemData.isEmpty = true;
+
+      problemData.Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", new Dataset()));
+      problemData.Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, ""));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
+      problemData.Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, "", new StringMatrix(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, "", (DoubleMatrix)new DoubleMatrix(0, 0).AsReadOnly()));
+      emptyProblemData = problemData;
+    }
+    #endregion
+
+    #region parameter properties
+    public IConstrainedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+    public IFixedValueParameter<StringMatrix> ClassNamesParameter {
+      get { return (IFixedValueParameter<StringMatrix>)Parameters[ClassNamesParameterName]; }
+    }
+    public IFixedValueParameter<DoubleMatrix> ClassificationPenaltiesParameter {
+      get { return (IFixedValueParameter<DoubleMatrix>)Parameters[ClassificationPenaltiesParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    private List<double> classValuesCache;
+    private List<double> ClassValuesCache {
+      get {
+        if (classValuesCache == null) {
+          classValuesCache = Dataset.GetDoubleValues(TargetVariableParameter.Value.Value).Distinct().OrderBy(x => x).ToList();
+        }
+        return classValuesCache;
+      }
+    }
+    public IEnumerable<double> ClassValues {
+      get { return ClassValuesCache; }
+    }
+    public int Classes {
+      get { return ClassValuesCache.Count; }
+    }
+
+    private List<string> classNamesCache;
+    private List<string> ClassNamesCache {
+      get {
+        if (classNamesCache == null) {
+          classNamesCache = new List<string>();
+          for (int i = 0; i < ClassNamesParameter.Value.Rows; i++)
+            classNamesCache.Add(ClassNamesParameter.Value[i, 0]);
+        }
+        return classNamesCache;
+      }
+    }
+    public IEnumerable<string> ClassNames {
+      get { return ClassNamesCache; }
+    }
+    #endregion
+
+
+    [StorableConstructor]
+    protected ClassificationProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+    protected ClassificationProblemData(ClassificationProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (this == emptyProblemData) return emptyProblemData;
+      return new ClassificationProblemData(this, cloner);
+    }
+
+    public ClassificationProblemData() : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) { }
+
+    public ClassificationProblemData(IClassificationProblemData classificationProblemData)
+      : this(classificationProblemData.Dataset, classificationProblemData.AllowedInputVariables, classificationProblemData.TargetVariable) {
+      TrainingPartition.Start = classificationProblemData.TrainingPartition.Start;
+      TrainingPartition.End = classificationProblemData.TrainingPartition.End;
+      TestPartition.Start = classificationProblemData.TestPartition.Start;
+      TestPartition.End = classificationProblemData.TestPartition.End;
+
+      for (int i = 0; i < classificationProblemData.ClassNames.Count(); i++)
+        ClassNamesParameter.Value[i, 0] = classificationProblemData.ClassNames.ElementAt(i);
+
+      for (int i = 0; i < Classes; i++) {
+        for (int j = 0; j < Classes; j++) {
+          ClassificationPenaltiesParameter.Value[i, j] = classificationProblemData.GetClassificationPenalty(ClassValuesCache[i], ClassValuesCache[j]);
+        }
+      }
+    }
+
+    public ClassificationProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables) {
+      var validTargetVariableValues = CheckVariablesForPossibleTargetVariables(dataset).Select(x => new StringValue(x).AsReadOnly()).ToList();
+      var target = validTargetVariableValues.Where(x => x.Value == targetVariable).DefaultIfEmpty(validTargetVariableValues.First()).First();
+
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(validTargetVariableValues), target));
+      Parameters.Add(new FixedValueParameter<StringMatrix>(ClassNamesParameterName, ""));
+      Parameters.Add(new FixedValueParameter<DoubleMatrix>(ClassificationPenaltiesParameterName, ""));
+
+      RegisterParameterEvents();
+      ResetTargetVariableDependentMembers();
+    }
+
+    private static IEnumerable<string> CheckVariablesForPossibleTargetVariables(Dataset dataset) {
+      int maxSamples = Math.Min(InspectedRowsToDetermineTargets, dataset.Rows);
+      var validTargetVariables = (from v in dataset.DoubleVariables
+                                  let distinctValues = dataset.GetDoubleValues(v)
+                                    .Take(maxSamples)
+                                    .Distinct()
+                                    .Count()
+                                  where distinctValues < MaximumNumberOfClasses
+                                  select v).ToArray();
+
+      if (!validTargetVariables.Any())
+        throw new ArgumentException("Import of classification problem data was not successful, because no target variable was found." +
+          " A target variable must have at most " + MaximumNumberOfClasses + " distinct values to be applicable to classification.");
+      return validTargetVariables;
+    }
+
+
+    private void ResetTargetVariableDependentMembers() {
+      DeregisterParameterEvents();
+
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Columns = 1;
+      ((IStringConvertibleMatrix)ClassNamesParameter.Value).Rows = ClassValuesCache.Count;
+      for (int i = 0; i < Classes; i++)
+        ClassNamesParameter.Value[i, 0] = "Class " + ClassValuesCache[i];
+      ClassNamesParameter.Value.ColumnNames = new List<string>() { "ClassNames" };
+      ClassNamesParameter.Value.RowNames = ClassValues.Select(s => "ClassValue: " + s);
+
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Rows = Classes;
+      ((IStringConvertibleMatrix)ClassificationPenaltiesParameter.Value).Columns = Classes;
+      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
+      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
+      for (int i = 0; i < Classes; i++) {
+        for (int j = 0; j < Classes; j++) {
+          if (i != j) ClassificationPenaltiesParameter.Value[i, j] = 1;
+          else ClassificationPenaltiesParameter.Value[i, j] = 0;
+        }
+      }
+      RegisterParameterEvents();
+    }
+
+    public string GetClassName(double classValue) {
+      if (!ClassValuesCache.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValuesCache.IndexOf(classValue);
+      return ClassNamesCache[index];
+    }
+    public double GetClassValue(string className) {
+      if (!ClassNamesCache.Contains(className)) throw new ArgumentException();
+      int index = ClassNamesCache.IndexOf(className);
+      return ClassValuesCache[index];
+    }
+    public void SetClassName(double classValue, string className) {
+      if (!ClassValuesCache.Contains(classValue)) throw new ArgumentException();
+      int index = ClassValuesCache.IndexOf(classValue);
+      ClassNamesParameter.Value[index, 0] = className;
+      // updating of class names cache is not necessary here as the parameter value fires a changed event which updates the cache
+    }
+
+    public double GetClassificationPenalty(string correctClassName, string estimatedClassName) {
+      return GetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName));
+    }
+    public double GetClassificationPenalty(double correctClassValue, double estimatedClassValue) {
+      int correctClassIndex = ClassValuesCache.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValuesCache.IndexOf(estimatedClassValue);
+      return ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex];
+    }
+    public void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty) {
+      SetClassificationPenalty(GetClassValue(correctClassName), GetClassValue(estimatedClassName), penalty);
+    }
+    public void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty) {
+      int correctClassIndex = ClassValuesCache.IndexOf(correctClassValue);
+      int estimatedClassIndex = ClassValuesCache.IndexOf(estimatedClassValue);
+
+      ClassificationPenaltiesParameter.Value[correctClassIndex, estimatedClassIndex] = penalty;
+    }
+
+    #region events
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged += new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.Reset += new EventHandler(Parameter_ValueChanged);
+    }
+    private void DeregisterParameterEvents() {
+      TargetVariableParameter.ValueChanged -= new EventHandler(TargetVariableParameter_ValueChanged);
+      ClassNamesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+      ClassNamesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.ItemChanged -= new EventHandler<EventArgs<int, int>>(Parameter_ValueChanged);
+      ClassificationPenaltiesParameter.Value.Reset -= new EventHandler(Parameter_ValueChanged);
+    }
+
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      classValuesCache = null;
+      classNamesCache = null;
+      ResetTargetVariableDependentMembers();
+      OnChanged();
+    }
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      classNamesCache = null;
+      ClassificationPenaltiesParameter.Value.RowNames = ClassNames.Select(name => "Actual " + name);
+      ClassificationPenaltiesParameter.Value.ColumnNames = ClassNames.Select(name => "Estimated " + name);
+      OnChanged();
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolution.cs	(revision 16097)
@@ -0,0 +1,82 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a classification data analysis solution
+  /// </summary>
+  [StorableClass]
+  public abstract class ClassificationSolution : ClassificationSolutionBase {
+    protected readonly Dictionary<int, double> evaluationCache;
+
+    [StorableConstructor]
+    protected ClassificationSolution(bool deserializing)
+      : base(deserializing) {
+      evaluationCache = new Dictionary<int, double>();
+    }
+    protected ClassificationSolution(ClassificationSolution original, Cloner cloner)
+      : base(original, cloner) {
+      evaluationCache = new Dictionary<int, double>(original.evaluationCache);
+    }
+    public ClassificationSolution(IClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
+      CalculateClassificationResults();
+    }
+
+    public override IEnumerable<double> EstimatedClassValues {
+      get { return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingClassValues {
+      get { return GetEstimatedClassValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestClassValues {
+      get { return GetEstimatedClassValues(ProblemData.TestIndices); }
+    }
+
+    public override IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedClassValues(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
+    }
+
+    protected override void OnProblemDataChanged() {
+      evaluationCache.Clear();
+      base.OnProblemDataChanged();
+    }
+
+    protected override void OnModelChanged() {
+      evaluationCache.Clear();
+      base.OnModelChanged();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ClassificationSolutionBase.cs	(revision 16097)
@@ -0,0 +1,121 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class ClassificationSolutionBase : DataAnalysisSolution, IClassificationSolution {
+    private const string TrainingAccuracyResultName = "Accuracy (training)";
+    private const string TestAccuracyResultName = "Accuracy (test)";
+    private const string TrainingNormalizedGiniCoefficientResultName = "Normalized Gini Coefficient (training)";
+    private const string TestNormalizedGiniCoefficientResultName = "Normalized Gini Coefficient (test)";
+
+    public new IClassificationModel Model {
+      get { return (IClassificationModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new IClassificationProblemData ProblemData {
+      get { return (IClassificationProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    #region Results
+    public double TrainingAccuracy {
+      get { return ((DoubleValue)this[TrainingAccuracyResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingAccuracyResultName].Value).Value = value; }
+    }
+    public double TestAccuracy {
+      get { return ((DoubleValue)this[TestAccuracyResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestAccuracyResultName].Value).Value = value; }
+    }
+    public double TrainingNormalizedGiniCoefficient {
+      get { return ((DoubleValue)this[TrainingNormalizedGiniCoefficientResultName].Value).Value; }
+      protected set { ((DoubleValue)this[TrainingNormalizedGiniCoefficientResultName].Value).Value = value; }
+    }
+    public double TestNormalizedGiniCoefficient {
+      get { return ((DoubleValue)this[TestNormalizedGiniCoefficientResultName].Value).Value; }
+      protected set { ((DoubleValue)this[TestNormalizedGiniCoefficientResultName].Value).Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected ClassificationSolutionBase(bool deserializing) : base(deserializing) { }
+    protected ClassificationSolutionBase(ClassificationSolutionBase original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    protected ClassificationSolutionBase(IClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingAccuracyResultName, "Accuracy of the model on the training partition (percentage of correctly classified instances).", new PercentValue()));
+      Add(new Result(TestAccuracyResultName, "Accuracy of the model on the test partition (percentage of correctly classified instances).", new PercentValue()));
+      Add(new Result(TrainingNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the training partition.", new DoubleValue()));
+      Add(new Result(TestNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the test partition.", new DoubleValue()));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (!this.ContainsKey(TrainingNormalizedGiniCoefficientResultName))
+        Add(new Result(TrainingNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the training partition.", new DoubleValue()));
+      if (!this.ContainsKey(TestNormalizedGiniCoefficientResultName))
+        Add(new Result(TestNormalizedGiniCoefficientResultName, "Normalized Gini coefficient of the model on the test partition.", new DoubleValue()));
+    }
+
+    protected void CalculateClassificationResults() {
+      double[] estimatedTrainingClassValues = EstimatedTrainingClassValues.ToArray(); // cache values
+      double[] originalTrainingClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToArray();
+      double[] estimatedTestClassValues = EstimatedTestClassValues.ToArray(); // cache values
+      double[] originalTestClassValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToArray();
+
+      OnlineCalculatorError errorState;
+      double trainingAccuracy = OnlineAccuracyCalculator.Calculate(originalTrainingClassValues, estimatedTrainingClassValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) trainingAccuracy = double.NaN;
+      double testAccuracy = OnlineAccuracyCalculator.Calculate(originalTestClassValues, estimatedTestClassValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) testAccuracy = double.NaN;
+
+      TrainingAccuracy = trainingAccuracy;
+      TestAccuracy = testAccuracy;
+
+      double trainingNormalizedGini = NormalizedGiniCalculator.Calculate(originalTrainingClassValues, estimatedTrainingClassValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) trainingNormalizedGini = double.NaN;
+      double testNormalizedGini = NormalizedGiniCalculator.Calculate(originalTestClassValues, estimatedTestClassValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) testNormalizedGini = double.NaN;
+
+      TrainingNormalizedGiniCoefficient = trainingNormalizedGini;
+      TestNormalizedGiniCoefficient = testNormalizedGini;
+    }
+
+    public abstract IEnumerable<double> EstimatedClassValues { get; }
+    public abstract IEnumerable<double> EstimatedTrainingClassValues { get; }
+    public abstract IEnumerable<double> EstimatedTestClassValues { get; }
+
+    public abstract IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows);
+
+    protected override void RecalculateResults() {
+      CalculateClassificationResults();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationModel.cs	(revision 16097)
@@ -0,0 +1,145 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents discriminant function classification data analysis models.
+  /// </summary>
+  [StorableClass]
+  [Item("DiscriminantFunctionClassificationModel", "Represents a classification model that uses a discriminant function and classification thresholds.")]
+  public class DiscriminantFunctionClassificationModel : NamedItem, IDiscriminantFunctionClassificationModel {
+    [Storable]
+    private IRegressionModel model;
+    public IRegressionModel Model {
+      get { return model; }
+      private set { model = value; }
+    }
+
+    [Storable]
+    private double[] classValues;
+    public IEnumerable<double> ClassValues {
+      get { return (double[])classValues.Clone(); }
+      private set { classValues = value.ToArray(); }
+    }
+
+    [Storable]
+    private double[] thresholds;
+    public IEnumerable<double> Thresholds {
+      get { return (IEnumerable<double>)thresholds.Clone(); }
+      private set { thresholds = value.ToArray(); }
+    }
+
+    private IDiscriminantFunctionThresholdCalculator thresholdCalculator;
+    [Storable]
+    public IDiscriminantFunctionThresholdCalculator ThresholdCalculator {
+      get { return thresholdCalculator; }
+      private set { thresholdCalculator = value; }
+    }
+
+
+    [StorableConstructor]
+    protected DiscriminantFunctionClassificationModel(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationModel(DiscriminantFunctionClassificationModel original, Cloner cloner)
+      : base(original, cloner) {
+      model = cloner.Clone(original.model);
+      classValues = (double[])original.classValues.Clone();
+      thresholds = (double[])original.thresholds.Clone();
+    }
+
+    public DiscriminantFunctionClassificationModel(IRegressionModel model, IDiscriminantFunctionThresholdCalculator thresholdCalculator)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.model = model;
+      this.classValues = new double[0];
+      this.thresholds = new double[0];
+      this.thresholdCalculator = thresholdCalculator;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      if (ThresholdCalculator == null) ThresholdCalculator = new AccuracyMaximizationThresholdCalculator();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscriminantFunctionClassificationModel(this, cloner);
+    }
+
+    public void SetThresholdsAndClassValues(IEnumerable<double> thresholds, IEnumerable<double> classValues) {
+      var classValuesArr = classValues.ToArray();
+      var thresholdsArr = thresholds.ToArray();
+      if (thresholdsArr.Length != classValuesArr.Length) throw new ArgumentException();
+
+      this.classValues = classValuesArr;
+      this.thresholds = thresholdsArr;
+      OnThresholdsChanged(EventArgs.Empty);
+    }
+
+    public virtual void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows) {
+      double[] classValues;
+      double[] thresholds;
+      var targetClassValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, rows);
+      var estimatedTrainingValues = GetEstimatedValues(problemData.Dataset, rows);
+      thresholdCalculator.Calculate(problemData, estimatedTrainingValues, targetClassValues, out classValues, out thresholds);
+      SetThresholdsAndClassValues(thresholds, classValues);
+    }
+
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      return model.GetEstimatedValues(dataset, rows);
+    }
+
+    public IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows) {
+      if (!Thresholds.Any() && !ClassValues.Any()) throw new ArgumentException("No thresholds and class values were set for the current classification model.");
+      foreach (var x in GetEstimatedValues(dataset, rows)) {
+        int classIndex = 0;
+        // find first threshold value which is larger than x => class index = threshold index + 1
+        for (int i = 0; i < thresholds.Length; i++) {
+          if (x > thresholds[i]) classIndex++;
+          else break;
+        }
+        yield return classValues.ElementAt(classIndex - 1);
+      }
+    }
+    #region events
+    public event EventHandler ThresholdsChanged;
+    protected virtual void OnThresholdsChanged(EventArgs e) {
+      var listener = ThresholdsChanged;
+      if (listener != null) listener(this, e);
+    }
+    #endregion
+
+    public virtual IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData) {
+      return new DiscriminantFunctionClassificationSolution(this, new ClassificationProblemData(problemData));
+    }
+
+    public virtual IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData) {
+      return CreateDiscriminantFunctionClassificationSolution(problemData);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolution.cs	(revision 16097)
@@ -0,0 +1,121 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a classification solution that uses a discriminant function and classification thresholds.
+  /// </summary>
+  [StorableClass]
+  [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
+  public class DiscriminantFunctionClassificationSolution : DiscriminantFunctionClassificationSolutionBase {
+    protected readonly Dictionary<int, double> valueEvaluationCache;
+    protected readonly Dictionary<int, double> classValueEvaluationCache;
+
+    [StorableConstructor]
+    protected DiscriminantFunctionClassificationSolution(bool deserializing)
+      : base(deserializing) {
+      valueEvaluationCache = new Dictionary<int, double>();
+      classValueEvaluationCache = new Dictionary<int, double>();
+    }
+    protected DiscriminantFunctionClassificationSolution(DiscriminantFunctionClassificationSolution original, Cloner cloner)
+      : base(original, cloner) {
+      valueEvaluationCache = new Dictionary<int, double>(original.valueEvaluationCache);
+      classValueEvaluationCache = new Dictionary<int, double>(original.classValueEvaluationCache);
+    }
+    public DiscriminantFunctionClassificationSolution(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      valueEvaluationCache = new Dictionary<int, double>();
+      classValueEvaluationCache = new Dictionary<int, double>();
+      CalculateRegressionResults();
+      CalculateClassificationResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new DiscriminantFunctionClassificationSolution(this, cloner);
+    }
+
+    public override IEnumerable<double> EstimatedClassValues {
+      get { return GetEstimatedClassValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingClassValues {
+      get { return GetEstimatedClassValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestClassValues {
+      get { return GetEstimatedClassValues(ProblemData.TestIndices); }
+    }
+
+    public override IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(classValueEvaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedClassValues(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        classValueEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => classValueEvaluationCache[row]);
+    }
+
+
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(valueEvaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedValues(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        valueEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => valueEvaluationCache[row]);
+    }
+
+    protected override void OnModelChanged() {
+      valueEvaluationCache.Clear();
+      classValueEvaluationCache.Clear();
+      base.OnModelChanged();
+    }
+    protected override void OnModelThresholdsChanged(System.EventArgs e) {
+      classValueEvaluationCache.Clear();
+      base.OnModelThresholdsChanged(e);
+    }
+    protected override void OnProblemDataChanged() {
+      valueEvaluationCache.Clear();
+      classValueEvaluationCache.Clear();
+      base.OnProblemDataChanged();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/DiscriminantFunctionClassificationSolutionBase.cs	(revision 16097)
@@ -0,0 +1,146 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a classification solution that uses a discriminant function and classification thresholds.
+  /// </summary>
+  [StorableClass]
+  [Item("DiscriminantFunctionClassificationSolution", "Represents a classification solution that uses a discriminant function and classification thresholds.")]
+  public abstract class DiscriminantFunctionClassificationSolutionBase : ClassificationSolutionBase, IDiscriminantFunctionClassificationSolution {
+    private const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    private const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+    private const string TrainingRSquaredResultName = "Pearson's R² (training)";
+    private const string TestRSquaredResultName = "Pearson's R² (test)";
+
+    public new IDiscriminantFunctionClassificationModel Model {
+      get { return (IDiscriminantFunctionClassificationModel)base.Model; }
+      protected set {
+        if (value != null && value != Model) {
+          if (Model != null) {
+            Model.ThresholdsChanged -= new EventHandler(Model_ThresholdsChanged);
+          }
+          value.ThresholdsChanged += new EventHandler(Model_ThresholdsChanged);
+          base.Model = value;
+        }
+      }
+    }
+
+    #region Results
+    public double TrainingMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanSquaredError {
+      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingRSquared {
+      get { return ((DoubleValue)this[TrainingRSquaredResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingRSquaredResultName].Value).Value = value; }
+    }
+    public double TestRSquared {
+      get { return ((DoubleValue)this[TestRSquaredResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestRSquaredResultName].Value).Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DiscriminantFunctionClassificationSolutionBase(bool deserializing) : base(deserializing) { }
+    protected DiscriminantFunctionClassificationSolutionBase(DiscriminantFunctionClassificationSolutionBase original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandler();
+    }
+    protected DiscriminantFunctionClassificationSolutionBase(IDiscriminantFunctionClassificationModel model, IClassificationProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingMeanSquaredErrorResultName, "Mean of squared errors of the model on the training partition", new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, "Mean of squared errors of the model on the test partition", new DoubleValue()));
+      Add(new Result(TrainingRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition", new DoubleValue()));
+      Add(new Result(TestRSquaredResultName, "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition", new DoubleValue()));
+      RegisterEventHandler();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandler();
+    }
+
+    protected void CalculateRegressionResults() {
+      double[] estimatedTrainingValues = EstimatedTrainingValues.ToArray(); // cache values
+      double[] originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToArray();
+      double[] estimatedTestValues = EstimatedTestValues.ToArray(); // cache values
+      double[] originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToArray();
+
+      OnlineCalculatorError errorState;
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+
+      double trainingNormalizedGini = NormalizedGiniCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) trainingNormalizedGini = double.NaN;
+      double testNormalizedGini = NormalizedGiniCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) testNormalizedGini = double.NaN;
+
+      TrainingNormalizedGiniCoefficient = trainingNormalizedGini;
+      TestNormalizedGiniCoefficient = testNormalizedGini;
+    }
+
+    private void RegisterEventHandler() {
+      Model.ThresholdsChanged += new EventHandler(Model_ThresholdsChanged);
+    }
+    private void DeregisterEventHandler() {
+      Model.ThresholdsChanged -= new EventHandler(Model_ThresholdsChanged);
+    }
+    private void Model_ThresholdsChanged(object sender, EventArgs e) {
+      OnModelThresholdsChanged(e);
+    }
+
+    protected virtual void OnModelThresholdsChanged(EventArgs e) {
+      OnModelChanged();
+    }
+
+    public abstract IEnumerable<double> EstimatedValues { get; }
+    public abstract IEnumerable<double> EstimatedTrainingValues { get; }
+    public abstract IEnumerable<double> EstimatedTestValues { get; }
+
+    public abstract IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateRegressionResults();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/AccuracyMaximizationThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,133 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.
+  /// </summary>
+  [StorableClass]
+  [Item("AccuracyMaximizationThresholdCalculator", "Represents a threshold calculator that maximizes the weighted accuracy of the classifcation model.")]
+  public class AccuracyMaximizationThresholdCalculator : ThresholdCalculator {
+
+    [StorableConstructor]
+    protected AccuracyMaximizationThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected AccuracyMaximizationThresholdCalculator(AccuracyMaximizationThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public AccuracyMaximizationThresholdCalculator()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AccuracyMaximizationThresholdCalculator(this, cloner);
+    }
+
+    public override void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      AccuracyMaximizationThresholdCalculator.CalculateThresholds(problemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+    }
+
+    public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      const int slices = 100;
+      const double minThresholdInc = 10e-5; // necessary to prevent infinite loop when maxEstimated - minEstimated is effectively zero (constant model)
+      List<double> estimatedValuesList = estimatedValues.ToList();
+      double maxEstimatedValue = estimatedValuesList.Max();
+      double minEstimatedValue = estimatedValuesList.Min();
+      double thresholdIncrement = Math.Max((maxEstimatedValue - minEstimatedValue) / slices, minThresholdInc);
+      var estimatedAndTargetValuePairs =
+        estimatedValuesList.Zip(targetClassValues, (x, y) => new { EstimatedValue = x, TargetClassValue = y })
+        .OrderBy(x => x.EstimatedValue).ToList();
+
+      classValues = estimatedAndTargetValuePairs.GroupBy(x => x.TargetClassValue)
+        .Select(x => new { Median = x.Select(y => y.EstimatedValue).Median(), Class = x.Key })
+        .OrderBy(x => x.Median).Select(x => x.Class).ToArray();
+
+      int nClasses = classValues.Length;
+      thresholds = new double[nClasses];
+      thresholds[0] = double.NegativeInfinity;
+
+      // incrementally calculate accuracy of all possible thresholds
+      for (int i = 1; i < thresholds.Length; i++) {
+        double lowerThreshold = thresholds[i - 1];
+        double actualThreshold = Math.Max(lowerThreshold, minEstimatedValue);
+        double lowestBestThreshold = double.NaN;
+        double highestBestThreshold = double.NaN;
+        double bestClassificationScore = double.PositiveInfinity;
+        bool seriesOfEqualClassificationScores = false;
+
+        while (actualThreshold < maxEstimatedValue) {
+          double classificationScore = 0.0;
+
+          foreach (var pair in estimatedAndTargetValuePairs) {
+            //all positives
+            if (pair.TargetClassValue.IsAlmost(classValues[i - 1])) {
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue <= actualThreshold)
+                //true positive
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, pair.TargetClassValue);
+              else
+                //false negative
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i]);
+            }
+              //all negatives
+            else {
+              //false positive
+              if (pair.EstimatedValue > lowerThreshold && pair.EstimatedValue <= actualThreshold)
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i - 1]);
+              else if (pair.EstimatedValue <= lowerThreshold)
+                classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i - 2]);
+              else if (pair.EstimatedValue > actualThreshold) {
+                if (pair.TargetClassValue < classValues[i - 1]) //negative in wrong class, consider upper class
+                  classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, classValues[i]);
+                else //true negative, must be optimized by the other thresholds
+                  classificationScore += problemData.GetClassificationPenalty(pair.TargetClassValue, pair.TargetClassValue);
+              }
+            }
+          }
+
+          //new best classification score found
+          if (classificationScore < bestClassificationScore) {
+            bestClassificationScore = classificationScore;
+            lowestBestThreshold = actualThreshold;
+            highestBestThreshold = actualThreshold;
+            seriesOfEqualClassificationScores = true;
+          }
+            //equal classification scores => if seriesOfEqualClassifcationScores == true update highest threshold
+          else if (Math.Abs(classificationScore - bestClassificationScore) < double.Epsilon && seriesOfEqualClassificationScores)
+            highestBestThreshold = actualThreshold;
+          //worse classificatoin score found reset seriesOfEqualClassifcationScores
+          else seriesOfEqualClassificationScores = false;
+
+          actualThreshold += thresholdIncrement;
+        }
+        //scale lowest thresholds and highest found optimal threshold according to the misclassification matrix
+        double falseNegativePenalty = problemData.GetClassificationPenalty(classValues[i], classValues[i - 1]);
+        double falsePositivePenalty = problemData.GetClassificationPenalty(classValues[i - 1], classValues[i]);
+        thresholds[i] = (lowestBestThreshold * falsePositivePenalty + highestBestThreshold * falseNegativePenalty) / (falseNegativePenalty + falsePositivePenalty);
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/NormalDistributionCutPointsThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,194 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).
+  /// </summary>
+  [StorableClass]
+  [Item("NormalDistributionCutPointsThresholdCalculator", "Represents a threshold calculator that calculates thresholds as the cutting points between the estimated class distributions (assuming normally distributed class values).")]
+  public class NormalDistributionCutPointsThresholdCalculator : ThresholdCalculator {
+
+    [StorableConstructor]
+    protected NormalDistributionCutPointsThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected NormalDistributionCutPointsThresholdCalculator(NormalDistributionCutPointsThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public NormalDistributionCutPointsThresholdCalculator()
+      : base() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NormalDistributionCutPointsThresholdCalculator(this, cloner);
+    }
+
+    public override void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      NormalDistributionCutPointsThresholdCalculator.CalculateThresholds(problemData, estimatedValues, targetClassValues, out classValues, out thresholds);
+    }
+
+    public static void CalculateThresholds(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds) {
+      var estimatedTargetValues = Enumerable.Zip(estimatedValues, targetClassValues, (e, t) => new { EstimatedValue = e, TargetValue = t }).ToList();
+      double estimatedValuesRange = estimatedValues.Range();
+
+      Dictionary<double, double> classMean = new Dictionary<double, double>();
+      Dictionary<double, double> classStdDev = new Dictionary<double, double>();
+      // calculate moments per class
+      foreach (var group in estimatedTargetValues.GroupBy(p => p.TargetValue)) {
+        IEnumerable<double> estimatedClassValues = group.Select(x => x.EstimatedValue);
+        double classValue = group.Key;
+        double mean, variance;
+        OnlineCalculatorError meanErrorState, varianceErrorState;
+        OnlineMeanAndVarianceCalculator.Calculate(estimatedClassValues, out mean, out variance, out meanErrorState, out varianceErrorState);
+
+        if (meanErrorState == OnlineCalculatorError.None && varianceErrorState == OnlineCalculatorError.None) {
+          classMean[classValue] = mean;
+          classStdDev[classValue] = Math.Sqrt(variance);
+        }
+      }
+      double[] originalClasses = classMean.Keys.OrderBy(x => x).ToArray();
+      int nClasses = originalClasses.Length;
+      List<double> thresholdList = new List<double>();
+      for (int i = 0; i < nClasses - 1; i++) {
+        for (int j = i + 1; j < nClasses; j++) {
+          double x1, x2;
+          double class0 = originalClasses[i];
+          double class1 = originalClasses[j];
+          // calculate all thresholds
+          CalculateCutPoints(classMean[class0], classStdDev[class0], classMean[class1], classStdDev[class1], out x1, out x2);
+
+          // if the two cut points are too close (for instance because the stdDev=0)
+          // then move them by 0.1% of the range of estimated values
+          if (x1.IsAlmost(x2)) {
+            x1 -= 0.001 * estimatedValuesRange;
+            x2 += 0.001 * estimatedValuesRange;
+          }
+          if (!double.IsInfinity(x1) && !thresholdList.Any(x => x.IsAlmost(x1))) thresholdList.Add(x1);
+          if (!double.IsInfinity(x2) && !thresholdList.Any(x => x.IsAlmost(x2))) thresholdList.Add(x2);
+        }
+      }
+      thresholdList.Sort();
+
+      // add small value and large value for the calculation of most influential class in each thresholded section
+      thresholdList.Insert(0, estimatedValues.Min() - 1);
+      thresholdList.Add(estimatedValues.Max() + 1);
+
+      // determine class values for each partition separated by a threshold by calculating the density of all class distributions
+      // all points in the partition are classified as the class with the maximal density in the parition
+      List<double> classValuesList = new List<double>();
+      if (thresholdList.Count == 2) {
+        // this happens if there are no thresholds (distributions for all classes are exactly the same)
+        // -> all samples should be classified as the first class
+        classValuesList.Add(originalClasses[0]);
+      } else {
+        // at least one reasonable threshold ...
+        // find the most likely class for the points between thresholds m
+        for (int i = 0; i < thresholdList.Count - 1; i++) {
+
+          // determine class with maximal density mass between the thresholds
+          double maxDensity = LogNormalDensityMass(thresholdList[i], thresholdList[i + 1], classMean[originalClasses[0]], classStdDev[originalClasses[0]]);
+          double maxDensityClassValue = originalClasses[0];
+          foreach (var classValue in originalClasses.Skip(1)) {
+            double density = LogNormalDensityMass(thresholdList[i], thresholdList[i + 1], classMean[classValue], classStdDev[classValue]);
+            if (density > maxDensity) {
+              maxDensity = density;
+              maxDensityClassValue = classValue;
+            }
+          }
+          classValuesList.Add(maxDensityClassValue);
+        }
+      }
+
+      // only keep thresholds at which the class changes 
+      // class B overrides threshold s. So only thresholds r and t are relevant and have to be kept
+      // 
+      //      A    B  C
+      //       /\  /\/\        
+      //      / r\/ /\t\       
+      //     /   /\/  \ \      
+      //    /   / /\s  \ \     
+      //  -/---/-/ -\---\-\----
+
+      List<double> filteredThresholds = new List<double>();
+      List<double> filteredClassValues = new List<double>();
+      filteredThresholds.Add(double.NegativeInfinity); // the smallest possible threshold for the first class
+      filteredClassValues.Add(classValuesList[0]);
+      // do not include the last threshold which was just needed for the previous step
+      for (int i = 0; i < classValuesList.Count - 1; i++) {
+        if (!classValuesList[i].IsAlmost(classValuesList[i + 1])) {
+          filteredThresholds.Add(thresholdList[i + 1]);
+          filteredClassValues.Add(classValuesList[i + 1]);
+        }
+      }
+      thresholds = filteredThresholds.ToArray();
+      classValues = filteredClassValues.ToArray();
+    }
+
+    private static double LogNormalDensityMass(double lower, double upper, double mu, double sigma) {
+      if (sigma.IsAlmost(0.0)) {
+        if (lower < mu && mu < upper) return double.PositiveInfinity; // log(1)
+        else return double.NegativeInfinity; // log(0)
+      }
+
+      Func<double, double> f = (x) =>
+        x * -0.5 * Math.Log(2.0 * Math.PI * sigma * sigma) - Math.Pow(x - mu, 3) / (3 * 2.0 * sigma * sigma);
+
+      if (double.IsNegativeInfinity(lower)) return f(upper);
+      else return f(upper) - f(lower);
+    }
+
+    private static void CalculateCutPoints(double m1, double s1, double m2, double s2, out double x1, out double x2) {
+      if (s1.IsAlmost(s2)) {
+        if (m1.IsAlmost(m2)) {
+          x1 = double.NegativeInfinity;
+          x2 = double.NegativeInfinity;
+        } else {
+          x1 = (m1 + m2) / 2;
+          x2 = double.NegativeInfinity;
+        }
+      } else if (s1.IsAlmost(0.0)) {
+        x1 = m1;
+        x2 = m1;
+      } else if (s2.IsAlmost(0.0)) {
+        x1 = m2;
+        x2 = m2;
+      } else {
+        if (s2 < s1) {
+          // make sure s2 is the larger std.dev.
+          CalculateCutPoints(m2, s2, m1, s1, out x1, out x2);
+        } else {
+          double a = (s1 + s2) * (s1 - s2);
+          double g = Math.Sqrt(s1 * s1 * s2 * s2 * ((m1 - m2) * (m1 - m2) + 2.0 * (s1 * s1 + s2 * s2) * Math.Log(s2 / s1)));
+          double m1s2 = m1 * s2 * s2;
+          double m2s1 = m2 * s1 * s1;
+          x1 = -(-m2s1 + m1s2 + g) / a;
+          x2 = (m2s1 - m1s2 + g) / a;
+        }
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/ThresholdCalculators/ThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,47 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Base class for threshold calculators for discriminant function classification models.
+  /// </summary>
+  [StorableClass]
+  public abstract class ThresholdCalculator : NamedItem, IDiscriminantFunctionThresholdCalculator {
+
+    [StorableConstructor]
+    protected ThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected ThresholdCalculator(ThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ThresholdCalculator()
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+    }
+
+    public abstract void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AccuracyWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AccuracyWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AccuracyWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,52 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a weight calculator that gives every classification solution a weight based on the accuracy.
+  /// </summary>
+  [StorableClass]
+  [Item("AccuracyWeightCalculator", "Represents a weight calculator that gives every classification solution a weight based on the accuracy.")]
+  public class AccuracyWeightCalculator : ClassificationWeightCalculator {
+
+    public AccuracyWeightCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected AccuracyWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected AccuracyWeightCalculator(AccuracyWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AccuracyWeightCalculator(this, cloner);
+    }
+
+    protected override IEnumerable<double> CalculateWeights(IEnumerable<IClassificationSolution> classificationSolutions) {
+      return classificationSolutions.Select(s => s.TrainingAccuracy);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("AverageThresholdCalculator", "")]
+  public class AverageThresholdCalculator : DiscriminantClassificationWeightCalculator {
+
+    public AverageThresholdCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected AverageThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected AverageThresholdCalculator(AverageThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AverageThresholdCalculator(this, cloner);
+    }
+
+    protected double[] threshold;
+    protected double[] classValues;
+
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      classValues = discriminantSolutions.First().Model.ClassValues.ToArray();
+      var modelThresholds = discriminantSolutions.Select(x => x.Model.Thresholds.ToArray());
+      threshold = new double[modelThresholds.First().GetLength(0)];
+      for (int i = 0; i < modelThresholds.First().GetLength(0); i++) {
+        threshold[i] = modelThresholds.Select(x => x[i]).Average();
+      }
+      return Enumerable.Repeat<double>(1, discriminantSolutions.Count());
+    }
+
+    protected override double GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      IList<double> values = solutions.Where(s => handler(s.ProblemData, index)).Select(s => s.Model.GetEstimatedValues(dataset, Enumerable.Repeat(index, 1)).First()).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double avg = values.Average();
+      return GetAverageConfidence(avg, estimatedClassValue);
+    }
+
+    public override IEnumerable<double> GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      List<int> indicesList = indices.ToList();
+      var solValues = solutions.ToDictionary(x => x, x => x.Model.GetEstimatedValues(dataset, indicesList).ToArray());
+      double[] confidences = new double[indices.Count()];
+      double[] estimatedClassValueArr = estimatedClassValue.ToArray();
+
+      for (int i = 0; i < indicesList.Count; i++) {
+        var values = solValues.Where(x => handler(x.Key.ProblemData, indicesList[i])).Select(x => x.Value[i]);
+        if (values.Count() <= 0) {
+          confidences[i] = double.NaN;
+        } else {
+          double avg = values.Average();
+          confidences[i] = GetAverageConfidence(avg, estimatedClassValueArr[i]);
+        }
+      }
+
+      return confidences;
+    }
+
+    protected double GetAverageConfidence(double avg, double estimatedClassValue) {
+      for (int i = 0; i < classValues.Length; i++) {
+        if (estimatedClassValue.Equals(classValues[i])) {
+          //special case: avgerage is higher than value of highest class
+          if (i == classValues.Length - 1 && avg >= estimatedClassValue) {
+            return 1;
+          }
+          //special case: average is lower than value of lowest class
+          if (i == 0 && avg < estimatedClassValue) {
+            return 1;
+          }
+          //special case: average is not between threshold of estimated class value
+          if ((i < classValues.Length - 1 && avg >= threshold[i + 1]) || avg <= threshold[i]) {
+            return 0;
+          }
+
+          double thresholdToClassDistance, thresholdToAverageValueDistance;
+          if (avg >= classValues[i]) {
+            thresholdToClassDistance = threshold[i + 1] - classValues[i];
+            thresholdToAverageValueDistance = threshold[i + 1] - avg;
+          } else {
+            thresholdToClassDistance = classValues[i] - threshold[i];
+            thresholdToAverageValueDistance = avg - threshold[i];
+          }
+          return (1 / thresholdToClassDistance) * thresholdToAverageValueDistance;
+        }
+      }
+      return double.NaN;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdClassificationCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdClassificationCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/AverageThresholdClassificationCalculator.cs	(revision 16097)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("AverageThresholdClassificationCalculator", "")]
+  public class AverageThresholdClassificationCalculator : AverageThresholdCalculator {
+
+    public AverageThresholdClassificationCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected AverageThresholdClassificationCalculator(bool deserializing) : base(deserializing) { }
+    protected AverageThresholdClassificationCalculator(AverageThresholdClassificationCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AverageThresholdClassificationCalculator(this, cloner);
+    }
+
+    protected override double DiscriminantAggregateEstimatedClassValues(IDictionary<IClassificationSolution, double> estimatedClassValues, IDictionary<IDiscriminantFunctionClassificationSolution, double> estimatedValues) {
+      IList<double> values = estimatedValues.Select(x => x.Value).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double avg = values.Average();
+      return GetClassValueToAverage(avg);
+    }
+    protected double GetClassValueToAverage(double avg) {
+      double classValue = classValues.First();
+      for (int i = 0; i < classValues.Count(); i++) {
+        if (avg > threshold[i])
+          classValue = classValues[i];
+        else
+          break;
+      }
+      return classValue;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ClassificationWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ClassificationWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ClassificationWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,157 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Base class for weight calculators for classification solutions in an ensemble.
+  /// </summary>
+  [StorableClass]
+  public abstract class ClassificationWeightCalculator : NamedItem, IClassificationEnsembleSolutionWeightCalculator {
+    [StorableConstructor]
+    protected ClassificationWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected ClassificationWeightCalculator(ClassificationWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ClassificationWeightCalculator()
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+    }
+
+    private IDictionary<IClassificationSolution, double> weights;
+
+    /// <summary>
+    /// calls CalculateWeights and removes negative weights 
+    /// </summary>
+    /// <param name="classificationSolutions"></param>
+    /// <returns>weights which are equal or bigger than zero</returns>
+    public void CalculateNormalizedWeights(IEnumerable<IClassificationSolution> classificationSolutions) {
+      List<double> weights = new List<double>();
+      if (classificationSolutions.Count() > 0) {
+        foreach (var weight in CalculateWeights(classificationSolutions)) {
+          weights.Add(weight >= 0 ? weight : 0);
+        }
+      }
+      double sum = weights.Sum();
+      this.weights = classificationSolutions.Zip(weights, (sol, wei) => new { sol, wei }).ToDictionary(x => x.sol, x => x.wei / sum);
+    }
+
+    protected abstract IEnumerable<double> CalculateWeights(IEnumerable<IClassificationSolution> classificationSolutions);
+
+    #region delegate CheckPoint
+    public CheckPoint GetTestClassDelegate() {
+      return PointInTest;
+    }
+    public CheckPoint GetTrainingClassDelegate() {
+      return PointInTraining;
+    }
+    public CheckPoint GetAllClassDelegate() {
+      return AllPoints;
+    }
+    #endregion
+
+    public virtual IEnumerable<double> AggregateEstimatedClassValues(IEnumerable<IClassificationSolution> solutions, Dataset dataset, IEnumerable<int> rows, CheckPoint handler) {
+      return from xs in GetEstimatedClassValues(solutions, dataset, rows, handler)
+             select AggregateEstimatedClassValues(xs);
+    }
+
+    protected double AggregateEstimatedClassValues(IDictionary<IClassificationSolution, double> estimatedClassValues) {
+      IDictionary<double, double> weightSum = new Dictionary<double, double>();
+      foreach (var item in estimatedClassValues) {
+        if (!weightSum.ContainsKey(item.Value))
+          weightSum[item.Value] = 0.0;
+        weightSum[item.Value] += weights[item.Key];
+      }
+      if (weightSum.Count <= 0)
+        return double.NaN;
+      var max = weightSum.Max(x => x.Value);
+      max = weightSum
+        .Where(x => x.Value.Equals(max))
+        .Select(x => x.Key)
+        .First();
+      return max;
+    }
+
+    protected IEnumerable<IDictionary<IClassificationSolution, double>> GetEstimatedClassValues(IEnumerable<IClassificationSolution> solutions, Dataset dataset, IEnumerable<int> rows, CheckPoint handler) {
+      var estimatedValuesEnumerators = (from solution in solutions
+                                        select new { Solution = solution, EstimatedValuesEnumerator = solution.Model.GetEstimatedClassValues(dataset, rows).GetEnumerator() })
+                                       .ToList();
+
+      var rowEnumerator = rows.GetEnumerator();
+      while (rowEnumerator.MoveNext() & estimatedValuesEnumerators.All(x => x.EstimatedValuesEnumerator.MoveNext())) {
+        yield return (from enumerator in estimatedValuesEnumerators
+                      where handler(enumerator.Solution.ProblemData, rowEnumerator.Current)
+                      select enumerator)
+                     .ToDictionary(x => x.Solution, x => x.EstimatedValuesEnumerator.Current);
+      }
+    }
+
+    public virtual double GetConfidence(IEnumerable<IClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1)
+        return double.NaN;
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      var correctSolutions = solutions.Select(s => new { Solution = s, Values = s.Model.GetEstimatedClassValues(dataset, Enumerable.Repeat(index, 1)).First() })
+                                      .Where(a => handler(a.Solution.ProblemData, index) && a.Values.Equals(estimatedClassValue))
+                                      .Select(a => a.Solution);
+      return (from sol in correctSolutions
+              select weights[sol]).Sum();
+    }
+
+    public virtual IEnumerable<double> GetConfidence(IEnumerable<IClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1)
+        return Enumerable.Repeat(double.NaN, indices.Count());
+
+      List<int> indicesList = indices.ToList();
+
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      Dictionary<IClassificationSolution, double[]> solValues = solutions.ToDictionary(x => x, x => x.Model.GetEstimatedClassValues(dataset, indicesList).ToArray());
+      double[] estimatedClassValueArr = estimatedClassValue.ToArray();
+      double[] confidences = new double[indicesList.Count];
+
+      for (int i = 0; i < indicesList.Count; i++) {
+        var correctSolutions = solValues.Where(x => DoubleExtensions.IsAlmost(x.Value[i], estimatedClassValueArr[i]));
+        confidences[i] = (from sol in correctSolutions
+                          where handler(sol.Key.ProblemData, indicesList[i])
+                          select weights[sol.Key]).Sum();
+      }
+
+      return confidences;
+    }
+
+    #region Helper
+    protected bool PointInTraining(IClassificationProblemData problemData, int point) {
+      return problemData.IsTrainingSample(point);
+    }
+    protected bool PointInTest(IClassificationProblemData problemData, int point) {
+      return problemData.IsTestSample(point);
+    }
+    protected bool AllPoints(IClassificationProblemData problemData, int point) {
+      return true;
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ContinuousPointCertaintyWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ContinuousPointCertaintyWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/ContinuousPointCertaintyWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// 
+  /// </summary>
+  [StorableClass]
+  [Item("ContinuousPointCertaintyWeightCalculator", "")]
+  public class ContinuousPointCertaintyWeightCalculator : DiscriminantClassificationWeightCalculator {
+
+    public ContinuousPointCertaintyWeightCalculator()
+      : base() {
+    }
+
+    [StorableConstructor]
+    protected ContinuousPointCertaintyWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected ContinuousPointCertaintyWeightCalculator(ContinuousPointCertaintyWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ContinuousPointCertaintyWeightCalculator(this, cloner);
+    }
+
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      List<double> weights = new List<double>();
+      IClassificationProblemData problemData = discriminantSolutions.ElementAt(0).ProblemData;
+      IEnumerable<double> targetValues;
+      IEnumerator<double> trainingValues;
+
+      //only works for binary classification
+      if (!problemData.ClassValues.Count().Equals(2))
+        return Enumerable.Repeat<double>(1, discriminantSolutions.Count());
+
+      double maxClass = problemData.ClassValues.Max();
+      double minClass = problemData.ClassValues.Min();
+      double halfDistanceBetweenClasses = (maxClass - minClass) / 2;
+
+      foreach (var solution in discriminantSolutions) {
+        problemData = solution.ProblemData;
+        targetValues = GetValues(problemData.Dataset.GetDoubleValues(problemData.TargetVariable).ToList(), problemData.TrainingIndizes);
+        trainingValues = targetValues.GetEnumerator();
+
+        IEnumerator<double> estimatedTrainingVal = solution.EstimatedTrainingValues.GetEnumerator();
+        IEnumerator<double> estimatedTrainingClassVal = solution.EstimatedTrainingClassValues.GetEnumerator();
+
+        double curWeight = 0.0;
+        while (estimatedTrainingVal.MoveNext() && estimatedTrainingClassVal.MoveNext() && trainingValues.MoveNext()) {
+          if (trainingValues.Current.Equals(maxClass)) {
+            if (estimatedTrainingVal.Current >= maxClass)
+              curWeight += 1.0;
+            else {
+              double distanceToPoint = Math.Abs(estimatedTrainingVal.Current - maxClass);
+              curWeight += Math.Max(1.0 - (1.0 / halfDistanceBetweenClasses) * distanceToPoint, -1.0);
+            }
+          } else if (trainingValues.Current.Equals(minClass)) {
+            if (estimatedTrainingVal.Current <= minClass)
+              curWeight += 1.0;
+            else {
+              double distanceToPoint = Math.Abs(estimatedTrainingVal.Current - minClass);
+              curWeight += Math.Max(1.0 - (1.0 / halfDistanceBetweenClasses) * distanceToPoint, -1.0);
+            }
+          }
+        }
+        // normalize the weight (otherwise a model with a bigger training partition would probably be better)
+        weights.Add(curWeight / targetValues.Count());
+      }
+      return weights;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/DiscriminantClassificationWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/DiscriminantClassificationWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/DiscriminantClassificationWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,110 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Base class for weight calculators for classification solutions in an ensemble.
+  /// </summary>
+  [StorableClass]
+  public abstract class DiscriminantClassificationWeightCalculator : ClassificationWeightCalculator {
+    [StorableConstructor]
+    protected DiscriminantClassificationWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected DiscriminantClassificationWeightCalculator(DiscriminantClassificationWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public DiscriminantClassificationWeightCalculator()
+      : base() {
+    }
+
+    protected override IEnumerable<double> CalculateWeights(IEnumerable<IClassificationSolution> classificationSolutions) {
+      if (!classificationSolutions.All(x => x is IDiscriminantFunctionClassificationSolution))
+        return Enumerable.Repeat<double>(1.0, classificationSolutions.Count());
+
+      IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions = classificationSolutions.Cast<IDiscriminantFunctionClassificationSolution>();
+
+      return DiscriminantCalculateWeights(discriminantSolutions);
+    }
+
+    protected abstract IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions);
+
+    public override IEnumerable<double> AggregateEstimatedClassValues(IEnumerable<IClassificationSolution> solutions, Dataset dataset, IEnumerable<int> rows, CheckPoint handler) {
+      if (!solutions.All(x => x is IDiscriminantFunctionClassificationSolution))
+        return Enumerable.Repeat<double>(double.NaN, rows.Count());
+
+      IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions = solutions.Cast<IDiscriminantFunctionClassificationSolution>();
+
+      IEnumerable<IDictionary<IClassificationSolution, double>> estimatedClassValues = GetEstimatedClassValues(solutions, dataset, rows, handler);
+      IEnumerable<IDictionary<IDiscriminantFunctionClassificationSolution, double>> estimatedValues = GetEstimatedValues(discriminantSolutions, dataset, rows, handler);
+
+      return from zip in estimatedClassValues.Zip(estimatedValues, (classValues, values) => new { ClassValues = classValues, Values = values })
+             select DiscriminantAggregateEstimatedClassValues(zip.ClassValues, zip.Values);
+    }
+
+    protected virtual double DiscriminantAggregateEstimatedClassValues(IDictionary<IClassificationSolution, double> estimatedClassValues, IDictionary<IDiscriminantFunctionClassificationSolution, double> estimatedValues) {
+      return base.AggregateEstimatedClassValues(estimatedClassValues);
+    }
+
+    protected IEnumerable<IDictionary<IDiscriminantFunctionClassificationSolution, double>> GetEstimatedValues(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, Dataset dataset, IEnumerable<int> rows, CheckPoint handler) {
+      var estimatedValuesEnumerators = (from solution in solutions
+                                        select new { Solution = solution, EstimatedValuesEnumerator = solution.Model.GetEstimatedValues(dataset, rows).GetEnumerator() })
+                                        .ToList();
+
+      var rowEnumerator = rows.GetEnumerator();
+      while (rowEnumerator.MoveNext() && estimatedValuesEnumerators.All(x => x.EstimatedValuesEnumerator.MoveNext())) {
+        yield return (from enumerator in estimatedValuesEnumerators
+                      where handler(enumerator.Solution.ProblemData, rowEnumerator.Current)
+                      select enumerator)
+                      .ToDictionary(x => x.Solution, x => x.EstimatedValuesEnumerator.Current);
+      }
+    }
+
+    public sealed override double GetConfidence(IEnumerable<IClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1 || !solutions.All(x => x is IDiscriminantFunctionClassificationSolution))
+        return double.NaN;
+
+      IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions = solutions.Cast<IDiscriminantFunctionClassificationSolution>();
+
+      return GetDiscriminantConfidence(discriminantSolutions, index, estimatedClassValue, handler);
+    }
+
+    protected virtual double GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      return base.GetConfidence(solutions, index, estimatedClassValue, handler);
+    }
+
+    public sealed override IEnumerable<double> GetConfidence(IEnumerable<IClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1 || !solutions.All(x => x is IDiscriminantFunctionClassificationSolution))
+        return Enumerable.Repeat(double.NaN, indices.Count());
+
+      IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions = solutions.Cast<IDiscriminantFunctionClassificationSolution>();
+
+      return GetDiscriminantConfidence(discriminantSolutions, indices, estimatedClassValue, handler);
+    }
+
+    public virtual IEnumerable<double> GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+      return base.GetConfidence(solutions, indices, estimatedClassValue, handler);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MajorityVoteWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MajorityVoteWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MajorityVoteWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,87 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a weight calculator that gives every classification solution the same weight.
+  /// </summary>
+  [StorableClass]
+  [Item("MajorityVoteWeightCalculator", "Represents a weight calculator that gives every classification solution the same weight.")]
+  public class MajorityVoteWeightCalculator : ClassificationWeightCalculator {
+
+    public MajorityVoteWeightCalculator()
+      : base() {
+    }
+
+    [StorableConstructor]
+    protected MajorityVoteWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected MajorityVoteWeightCalculator(MajorityVoteWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MajorityVoteWeightCalculator(this, cloner);
+    }
+
+    protected override IEnumerable<double> CalculateWeights(IEnumerable<IClassificationSolution> classificationSolutions) {
+      return Enumerable.Repeat<double>(1, classificationSolutions.Count());
+    }
+
+    public override double GetConfidence(IEnumerable<IClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1)
+        return double.NaN;
+      var votingSolutions = solutions.Where(s => handler(s.ProblemData, index));
+      if (votingSolutions.Count() < 1)
+        return double.NaN;
+      Dataset dataset = votingSolutions.First().ProblemData.Dataset;
+      int correctEstimated = votingSolutions.Select(s => s.Model.GetEstimatedClassValues(dataset, Enumerable.Repeat(index, 1)).First())
+                                      .Where(x => x.Equals(estimatedClassValue))
+                                      .Count();
+      return ((double)correctEstimated / (double)votingSolutions.Count() - 0.5) * 2;
+    }
+
+    public override IEnumerable<double> GetConfidence(IEnumerable<IClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+      if (solutions.Count() < 1)
+        return Enumerable.Repeat(double.NaN, indices.Count());
+
+      List<int> indicesList = indices.ToList();
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      var solValues = solutions.ToDictionary(x => x, x => x.Model.GetEstimatedClassValues(dataset, indicesList).ToArray());
+      double[] estimatedClassValueArr = estimatedClassValue.ToArray();
+      double correctEstimated;
+      double[] confidences = new double[indices.Count()];
+
+      for (int i = 0; i < indicesList.Count; i++) {
+        var votingSolutions = solValues.Where(x => handler(x.Key.ProblemData, indicesList[i]));
+        correctEstimated = votingSolutions.Where(x => DoubleExtensions.IsAlmost(x.Value[i], estimatedClassValueArr[i])).Count();
+        confidences[i] = (correctEstimated / (double)votingSolutions.Count() - 0.5) * 2;
+      }
+
+      return confidences;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianPointThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianPointThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianPointThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,147 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("MedianPointThresholdCalculator", "")]
+  public class MedianPointThresholdCalculator : DiscriminantClassificationWeightCalculator {
+
+    public MedianPointThresholdCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected MedianPointThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected MedianPointThresholdCalculator(MedianPointThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MedianPointThresholdCalculator(this, cloner);
+    }
+
+    protected double[] threshold;
+    protected double[] classValues;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="discriminantSolutions"></param>
+    /// <returns>median instead of weights, because it doesn't use any weights</returns>
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      List<List<double>> estimatedValues = new List<List<double>>();
+      List<List<double>> estimatedClassValues = new List<List<double>>();
+
+      List<IClassificationProblemData> solutionProblemData = discriminantSolutions.Select(sol => sol.ProblemData).ToList();
+      Dataset dataSet = solutionProblemData[0].Dataset;
+      IEnumerable<int> rows = Enumerable.Range(0, dataSet.Rows);
+      foreach (var solution in discriminantSolutions) {
+        estimatedValues.Add(solution.Model.GetEstimatedValues(dataSet, rows).ToList());
+        estimatedClassValues.Add(solution.Model.GetEstimatedValues(dataSet, rows).ToList());
+      }
+
+      List<double> median = new List<double>();
+      List<double> targetValues = dataSet.GetDoubleValues(solutionProblemData[0].TargetVariable).ToList();
+      IList<double> curTrainingpoints = new List<double>();
+      int removed = 0;
+      int count = targetValues.Count;
+      for (int point = 0; point < count; point++) {
+        curTrainingpoints.Clear();
+        for (int solutionPos = 0; solutionPos < solutionProblemData.Count; solutionPos++) {
+          if (PointInTraining(solutionProblemData[solutionPos], point)) {
+            curTrainingpoints.Add(estimatedValues[solutionPos][point]);
+          }
+        }
+        if (curTrainingpoints.Count > 0)
+          median.Add(GetMedian(curTrainingpoints.OrderBy(p => p).ToList()));
+        else {
+          //remove not used points
+          targetValues.RemoveAt(point - removed);
+          removed++;
+        }
+      }
+      AccuracyMaximizationThresholdCalculator.CalculateThresholds(solutionProblemData[0], median, targetValues, out classValues, out threshold);
+      return Enumerable.Repeat<double>(1, discriminantSolutions.Count());
+    }
+
+    protected override double DiscriminantAggregateEstimatedClassValues(IDictionary<IClassificationSolution, double> estimatedClassValues, IDictionary<IDiscriminantFunctionClassificationSolution, double> estimatedValues) {
+      IList<double> values = estimatedValues.Select(x => x.Value).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double median = GetMedian(values);
+      return GetClassValueToMedian(median);
+    }
+    private double GetClassValueToMedian(double median) {
+      double classValue = classValues.First();
+      for (int i = 0; i < classValues.Count(); i++) {
+        if (median > threshold[i])
+          classValue = classValues[i];
+        else
+          break;
+      }
+      return classValue;
+    }
+
+    protected override double GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, int index, double estimatedClassValue) {
+      // only works with binary classification
+      if (!classValues.Count().Equals(2))
+        return double.NaN;
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      IList<double> values = solutions.Select(s => s.Model.GetEstimatedValues(dataset, Enumerable.Repeat(index, 1)).First()).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double median = GetMedian(values);
+      if (estimatedClassValue.Equals(classValues[0])) {
+        if (median < estimatedClassValue)
+          return 1;
+        else if (median >= threshold[1])
+          return 0;
+        else {
+          double distance = threshold[1] - classValues[0];
+          return (1 / distance) * (median - classValues[0]);
+        }
+      } else if (estimatedClassValue.Equals(classValues[1])) {
+        if (median > estimatedClassValue)
+          return 1;
+        else if (median <= threshold[1])
+          return 0;
+        else {
+          double distance = classValues[1] - threshold[1];
+          return (1 / distance) * (classValues[1] - median);
+        }
+      } else
+        return double.NaN;
+    }
+
+    private double GetMedian(IList<double> estimatedValues) {
+      int count = estimatedValues.Count;
+      if (count % 2 == 0)
+        return 0.5 * (estimatedValues[count / 2 - 1] + estimatedValues[count / 2]);
+      else
+        return estimatedValues[count / 2];
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,127 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("MedianThresholdCalculator", "")]
+  public class MedianThresholdCalculator : DiscriminantClassificationWeightCalculator {
+
+    public MedianThresholdCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected MedianThresholdCalculator(bool deserializing) : base(deserializing) { }
+    protected MedianThresholdCalculator(MedianThresholdCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MedianThresholdCalculator(this, cloner);
+    }
+
+    protected double[] threshold;
+    protected double[] classValues;
+
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      classValues = discriminantSolutions.First().Model.ClassValues.ToArray();
+      var modelThresholds = discriminantSolutions.Select(x => x.Model.Thresholds.ToArray());
+      threshold = new double[modelThresholds.First().GetLength(0)];
+      for (int i = 0; i < modelThresholds.First().GetLength(0); i++) {
+        threshold[i] = GetMedian(modelThresholds.Select(x => x[i]).ToList());
+      }
+      return Enumerable.Repeat<double>(1, discriminantSolutions.Count());
+    }
+
+    protected override double GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler) {
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      IList<double> values = solutions.Where(s => handler(s.ProblemData, index)).Select(s => s.Model.GetEstimatedValues(dataset, Enumerable.Repeat(index, 1)).First()).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double median = GetMedian(values);
+      return GetMedianConfidence(median, estimatedClassValue);
+    }
+
+    public override IEnumerable<double> GetDiscriminantConfidence(IEnumerable<IDiscriminantFunctionClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler) {
+
+      Dataset dataset = solutions.First().ProblemData.Dataset;
+      List<int> indicesList = indices.ToList();
+      var solValues = solutions.ToDictionary(x => x, x => x.Model.GetEstimatedValues(dataset, indicesList).ToArray());
+      double[] confidences = new double[indices.Count()];
+      double[] estimatedClassValueArr = estimatedClassValue.ToArray();
+
+      for (int i = 0; i < indicesList.Count; i++) {
+        var values = solValues.Where(x => handler(x.Key.ProblemData, indicesList[i])).Select(x => x.Value[i]).ToList();
+        if (values.Count <= 0) {
+          confidences[i] = double.NaN;
+        } else {
+          double median = GetMedian(values);
+          confidences[i] = GetMedianConfidence(median, estimatedClassValueArr[i]);
+        }
+      }
+
+      return confidences;
+    }
+
+    protected double GetMedianConfidence(double median, double estimatedClassValue) {
+      for (int i = 0; i < classValues.Length; i++) {
+        if (estimatedClassValue.Equals(classValues[i])) {
+          //special case: median is higher than value of highest class
+          if (i == classValues.Length - 1 && median >= estimatedClassValue) {
+            return 1;
+          }
+          //special case: median is lower than value of lowest class
+          if (i == 0 && median < estimatedClassValue) {
+            return 1;
+          }
+          //special case: median is not between threshold of estimated class value
+          if ((i < classValues.Length - 1 && median >= threshold[i + 1]) || median <= threshold[i]) {
+            return 0;
+          }
+
+          double thresholdToClassDistance, thresholdToMedianValueDistance;
+          if (median >= classValues[i]) {
+            thresholdToClassDistance = threshold[i + 1] - classValues[i];
+            thresholdToMedianValueDistance = threshold[i + 1] - median;
+          } else {
+            thresholdToClassDistance = classValues[i] - threshold[i];
+            thresholdToMedianValueDistance = median - threshold[i];
+          }
+          return (1 / thresholdToClassDistance) * thresholdToMedianValueDistance;
+        }
+      }
+      return double.NaN;
+    }
+
+    protected double GetMedian(IList<double> estimatedValues) {
+      int count = estimatedValues.Count;
+      if (count % 2 == 0)
+        return 0.5 * (estimatedValues[count / 2 - 1] + estimatedValues[count / 2]);
+      else
+        return estimatedValues[count / 2];
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdClassificationCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdClassificationCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/MedianThresholdClassificationCalculator.cs	(revision 16097)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("MedianThresholdClassificationCalculator", "")]
+  public class MedianThresholdClassificationCalculator : MedianThresholdCalculator {
+
+    public MedianThresholdClassificationCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected MedianThresholdClassificationCalculator(bool deserializing) : base(deserializing) { }
+    protected MedianThresholdClassificationCalculator(MedianThresholdClassificationCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MedianThresholdClassificationCalculator(this, cloner);
+    }
+
+    protected override double DiscriminantAggregateEstimatedClassValues(IDictionary<IClassificationSolution, double> estimatedClassValues, IDictionary<IDiscriminantFunctionClassificationSolution, double> estimatedValues) {
+      IList<double> values = estimatedValues.Select(x => x.Value).ToList();
+      if (values.Count <= 0)
+        return double.NaN;
+      double median = GetMedian(values);
+      return GetClassValueToMedian(median);
+    }
+    private double GetClassValueToMedian(double median) {
+      double classValue = classValues.First();
+      for (int i = 0; i < classValues.Count(); i++) {
+        if (median > threshold[i])
+          classValue = classValues[i];
+        else
+          break;
+      }
+      return classValue;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/NeighbourhoodWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/NeighbourhoodWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/NeighbourhoodWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// 
+  /// </summary>
+  [StorableClass]
+  [Item("NeighbourhoodWeightCalculator", "")]
+  public class NeighbourhoodWeightCalculator : DiscriminantClassificationWeightCalculator {
+
+    public NeighbourhoodWeightCalculator()
+      : base() {
+    }
+
+    [StorableConstructor]
+    protected NeighbourhoodWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected NeighbourhoodWeightCalculator(NeighbourhoodWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new NeighbourhoodWeightCalculator(this, cloner);
+    }
+
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      List<List<double>> estimatedValues = new List<List<double>>();
+      List<List<double>> estimatedClassValues = new List<List<double>>();
+
+      List<IClassificationProblemData> solutionProblemData = discriminantSolutions.Select(sol => sol.ProblemData).ToList();
+      Dataset dataSet = solutionProblemData[0].Dataset;
+      IEnumerable<int> rows = Enumerable.Range(0, dataSet.Rows);
+      foreach (var solution in discriminantSolutions) {
+        estimatedValues.Add(solution.Model.GetEstimatedValues(dataSet, rows).ToList());
+        estimatedClassValues.Add(solution.Model.GetEstimatedClassValues(dataSet, rows).ToList());
+      }
+
+      List<double> weights = Enumerable.Repeat<double>(0, solutionProblemData.Count).ToList<double>();
+      List<double> targetValues = dataSet.GetDoubleValues(solutionProblemData[0].TargetVariable).ToList();
+
+      double pointAvg, help;
+      int count;
+      for (int point = 0; point < targetValues.Count; point++) {
+        pointAvg = 0.0;
+        count = 0;
+        for (int solutionPos = 0; solutionPos < estimatedClassValues.Count; solutionPos++) {
+          if (PointInTraining(solutionProblemData[solutionPos], point)
+              && estimatedClassValues[solutionPos][point].Equals(targetValues[point])) {
+            pointAvg += estimatedValues[solutionPos][point];
+            count++;
+          }
+        }
+        pointAvg /= (double)count;
+        for (int solutionPos = 0; solutionPos < estimatedClassValues.Count; solutionPos++) {
+          if (PointInTraining(solutionProblemData[solutionPos], point)
+              && estimatedClassValues[solutionPos][point].Equals(targetValues[point])) {
+            weights[solutionPos] += 0.5;
+            help = Math.Abs(estimatedValues[solutionPos][point] - 0.5);
+            weights[solutionPos] += help < 0.5 ? 0.5 - help : 0.0;
+          }
+        }
+      }
+      // normalize the weight (otherwise a model with a bigger training partition would probably be better)
+      for (int i = 0; i < weights.Count; i++) {
+        weights[i] = weights[i] / solutionProblemData[i].TrainingIndizes.Count();
+      }
+      return weights;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/PointCertaintyWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/PointCertaintyWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Classification/WeightCalculators/PointCertaintyWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,80 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("PointCertaintyWeightCalculator", "")]
+  public class PointCertaintyWeightCalculator : DiscriminantClassificationWeightCalculator {
+
+    public PointCertaintyWeightCalculator()
+      : base() {
+    }
+    [StorableConstructor]
+    protected PointCertaintyWeightCalculator(bool deserializing) : base(deserializing) { }
+    protected PointCertaintyWeightCalculator(PointCertaintyWeightCalculator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PointCertaintyWeightCalculator(this, cloner);
+    }
+
+    protected override IEnumerable<double> DiscriminantCalculateWeights(IEnumerable<IDiscriminantFunctionClassificationSolution> discriminantSolutions) {
+      List<double> weights = new List<double>();
+      IClassificationProblemData problemData = discriminantSolutions.ElementAt(0).ProblemData;
+      // class Values are the same in all problem data sets
+      double avg = problemData.ClassValues.Average();
+
+      IEnumerable<double> targetValues;
+      IEnumerator<double> trainingValues;
+
+      foreach (var solution in discriminantSolutions) {
+        problemData = solution.ProblemData;
+        targetValues = GetValues(problemData.Dataset.GetDoubleValues(problemData.TargetVariable).ToList(), problemData.TrainingIndizes);
+        trainingValues = targetValues.GetEnumerator();
+
+        IEnumerator<double> estimatedTrainingVal = solution.EstimatedTrainingValues.GetEnumerator();
+        IEnumerator<double> estimatedTrainingClassVal = solution.EstimatedTrainingClassValues.GetEnumerator();
+
+        double curWeight = 0.0;
+        while (estimatedTrainingVal.MoveNext() && estimatedTrainingClassVal.MoveNext() && trainingValues.MoveNext()) {
+          if (estimatedTrainingClassVal.Current.Equals(trainingValues.Current)) {
+            curWeight += 0.5;
+            double distanceToPoint = Math.Abs(estimatedTrainingVal.Current - avg);
+            double distanceToClass = Math.Abs(trainingValues.Current - avg);
+            if (trainingValues.Current > avg && estimatedTrainingVal.Current > avg
+             || trainingValues.Current < avg && estimatedTrainingVal.Current < avg)
+              curWeight += distanceToPoint < distanceToClass ? (0.5 / distanceToClass) * distanceToPoint : 0.5;
+          }
+        }
+        // normalize the weight (otherwise a model with a bigger training partition would probably be better)
+        weights.Add(curWeight / targetValues.Count());
+      }
+      return weights;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblem.cs	(revision 16097)
@@ -0,0 +1,41 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Clustering Problem", "A general clustering problem.")]
+  [Creatable("Problems")]
+  public class ClusteringProblem : DataAnalysisProblem<IClusteringProblemData>, IClusteringProblem {
+    [StorableConstructor]
+    protected ClusteringProblem(bool deserializing) : base(deserializing) { }
+    protected ClusteringProblem(ClusteringProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblem(this, cloner); }
+
+    public ClusteringProblem()
+      : base() {
+      ProblemData = new ClusteringProblemData();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringProblemData.cs	(revision 16097)
@@ -0,0 +1,92 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("ClusteringProblemData", "Represents an item containing all data defining a clustering problem.")]
+  public sealed class ClusteringProblemData : DataAnalysisProblemData, IClusteringProblemData, IStorableContent {
+    public string Filename { get; set; }
+
+    #region default data
+    private static double[,] kozaF1 = new double[,] {
+          {2.017885919,	-1.449165046},
+          {1.30060506,	-1.344523885},
+          {1.147134798,	-1.317989331},
+          {0.877182504,	-1.266142284},
+          {0.852562452,	-1.261020794},
+          {0.431095788,	-1.158793317},
+          {0.112586002,	-1.050908405},
+          {0.04594507,	-1.021989402},
+          {0.042572879,	-1.020438113},
+          {-0.074027291,	-0.959859562},
+          {-0.109178553,	-0.938094706},
+          {-0.259721109,	-0.803635355},
+          {-0.272991057,	-0.387519561},
+          {-0.161978191,	-0.193611001},
+          {-0.102489983,	-0.114215349},
+          {-0.01469968,	-0.014918985},
+          {-0.008863365,	-0.008942626},
+          {0.026751057,	0.026054094},
+          {0.166922436,	0.14309643},
+          {0.176953808,	0.1504144},
+          {0.190233418,	0.159916534},
+          {0.199800708,	0.166635331},
+          {0.261502822,	0.207600348},
+          {0.30182879,	0.232370249},
+          {0.83763905,	0.468046718}
+    };
+    private static Dataset defaultDataset;
+    private static IEnumerable<string> defaultAllowedInputVariables;
+
+    static ClusteringProblemData() {
+      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
+      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
+      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
+      defaultAllowedInputVariables = new List<string>() { "x", "y" };
+    }
+    #endregion
+
+    [StorableConstructor]
+    private ClusteringProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+    }
+
+
+    private ClusteringProblemData(ClusteringProblemData original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ClusteringProblemData(this, cloner); }
+
+    public ClusteringProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables) {
+    }
+
+    public ClusteringProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables)
+      : base(dataset, allowedInputVariables) {
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Clustering/ClusteringSolution.cs	(revision 16097)
@@ -0,0 +1,85 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a clustering data analysis solution
+  /// </summary>
+  [StorableClass]
+  public class ClusteringSolution : DataAnalysisSolution, IClusteringSolution {
+
+    [StorableConstructor]
+    protected ClusteringSolution(bool deserializing) : base(deserializing) { }
+    protected ClusteringSolution(ClusteringSolution original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public ClusteringSolution(IClusteringModel model, IClusteringProblemData problemData)
+      : base(model, problemData) {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ClusteringSolution(this, cloner);
+    }
+
+    protected override void RecalculateResults() {
+    }
+
+    #region IClusteringSolution Members
+
+    public new IClusteringModel Model {
+      get { return (IClusteringModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    public new IClusteringProblemData ProblemData {
+      get { return (IClusteringProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public virtual IEnumerable<int> ClusterValues {
+      get {
+        return GetClusterValues(Enumerable.Range(0, ProblemData.Dataset.Rows));
+      }
+    }
+
+    public virtual IEnumerable<int> TrainingClusterValues {
+      get {
+        return GetClusterValues(ProblemData.TrainingIndices);
+      }
+    }
+
+    public virtual IEnumerable<int> TestClusterValues {
+      get {
+        return GetClusterValues(ProblemData.TestIndices);
+      }
+    }
+
+    public virtual IEnumerable<int> GetClusterValues(IEnumerable<int> rows) {
+      return Model.GetClusterValues(ProblemData.Dataset, rows);
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblem.cs	(revision 16097)
@@ -0,0 +1,112 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.Instances;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class DataAnalysisProblem<T> : Problem, IDataAnalysisProblem<T>,
+    IProblemInstanceConsumer<T>, IProblemInstanceExporter<T>
+    where T : class, IDataAnalysisProblemData {
+    private const string ProblemDataParameterName = "ProblemData";
+    private const string ProblemDataParameterDescription = "The data set, target variable and input variables of the data analysis problem.";
+    #region parameter properties
+    IParameter IDataAnalysisProblem.ProblemDataParameter {
+      get { return ProblemDataParameter; }
+    }
+    public IValueParameter<T> ProblemDataParameter {
+      get { return (IValueParameter<T>)Parameters[ProblemDataParameterName]; }
+    }
+    #endregion
+    #region properties
+    IDataAnalysisProblemData IDataAnalysisProblem.ProblemData {
+      get { return ProblemData; }
+    }
+    public T ProblemData {
+      get { return ProblemDataParameter.Value; }
+      protected set {
+        ProblemDataParameter.Value = value;
+      }
+    }
+    #endregion
+    protected DataAnalysisProblem(DataAnalysisProblem<T> original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterEventHandlers();
+    }
+    [StorableConstructor]
+    protected DataAnalysisProblem(bool deserializing) : base(deserializing) { }
+    public DataAnalysisProblem()
+      : base() {
+      Parameters.Add(new ValueParameter<T>(ProblemDataParameterName, ProblemDataParameterDescription));
+      RegisterEventHandlers();
+    }
+
+    protected DataAnalysisProblem(T problemData)
+      : this() {
+      ProblemData = problemData;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      ProblemDataParameter.ValueChanged += new EventHandler(ProblemDataParameter_ValueChanged);
+      if (ProblemDataParameter.Value != null) ProblemDataParameter.Value.Changed += new EventHandler(ProblemData_Changed);
+    }
+
+    private void ProblemDataParameter_ValueChanged(object sender, EventArgs e) {
+      ProblemDataParameter.Value.Changed += new EventHandler(ProblemData_Changed);
+      OnProblemDataChanged();
+      OnReset();
+    }
+
+    private void ProblemData_Changed(object sender, EventArgs e) {
+      OnReset();
+    }
+
+    public event EventHandler ProblemDataChanged;
+    protected virtual void OnProblemDataChanged() {
+      var handler = ProblemDataChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    #region Import & Export
+    public void Load(T data) {
+      Name = data.Name;
+      Description = data.Description;
+      ProblemData = data;
+      OnReset();
+    }
+
+    public T Export() {
+      return ProblemData;
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisProblemData.cs	(revision 16097)
@@ -0,0 +1,161 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class DataAnalysisProblemData : ParameterizedNamedItem, IDataAnalysisProblemData {
+    protected const string DatasetParameterName = "Dataset";
+    protected const string InputVariablesParameterName = "InputVariables";
+    protected const string TrainingPartitionParameterName = "TrainingPartition";
+    protected const string TestPartitionParameterName = "TestPartition";
+
+    #region parameter properites
+    public IFixedValueParameter<Dataset> DatasetParameter {
+      get { return (IFixedValueParameter<Dataset>)Parameters[DatasetParameterName]; }
+    }
+    public IFixedValueParameter<ReadOnlyCheckedItemList<StringValue>> InputVariablesParameter {
+      get { return (IFixedValueParameter<ReadOnlyCheckedItemList<StringValue>>)Parameters[InputVariablesParameterName]; }
+    }
+    public IFixedValueParameter<IntRange> TrainingPartitionParameter {
+      get { return (IFixedValueParameter<IntRange>)Parameters[TrainingPartitionParameterName]; }
+    }
+    public IFixedValueParameter<IntRange> TestPartitionParameter {
+      get { return (IFixedValueParameter<IntRange>)Parameters[TestPartitionParameterName]; }
+    }
+    #endregion
+
+    #region properties
+    protected bool isEmpty = false;
+    public bool IsEmpty {
+      get { return isEmpty; }
+    }
+    public Dataset Dataset {
+      get { return DatasetParameter.Value; }
+    }
+    public ICheckedItemList<StringValue> InputVariables {
+      get { return InputVariablesParameter.Value; }
+    }
+    public IEnumerable<string> AllowedInputVariables {
+      get { return InputVariables.CheckedItems.Select(x => x.Value.Value); }
+    }
+
+    public IntRange TrainingPartition {
+      get { return TrainingPartitionParameter.Value; }
+    }
+    public IntRange TestPartition {
+      get { return TestPartitionParameter.Value; }
+    }
+
+    public virtual IEnumerable<int> TrainingIndices {
+      get {
+        return Enumerable.Range(TrainingPartition.Start, Math.Max(0, TrainingPartition.End - TrainingPartition.Start))
+                         .Where(IsTrainingSample);
+      }
+    }
+    public virtual IEnumerable<int> TestIndices {
+      get {
+        return Enumerable.Range(TestPartition.Start, Math.Max(0, TestPartition.End - TestPartition.Start))
+           .Where(IsTestSample);
+      }
+    }
+
+    public virtual bool IsTrainingSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+        TrainingPartition.Start <= index && index < TrainingPartition.End &&
+        (index < TestPartition.Start || TestPartition.End <= index);
+    }
+
+    public virtual bool IsTestSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+             TestPartition.Start <= index && index < TestPartition.End;
+    }
+    #endregion
+
+    protected DataAnalysisProblemData(DataAnalysisProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      isEmpty = original.isEmpty;
+      RegisterEventHandlers();
+    }
+    [StorableConstructor]
+    protected DataAnalysisProblemData(bool deserializing) : base(deserializing) { }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    protected DataAnalysisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables) {
+      if (dataset == null) throw new ArgumentNullException("The dataset must not be null.");
+      if (allowedInputVariables == null) throw new ArgumentNullException("The allowedInputVariables must not be null.");
+
+      if (allowedInputVariables.Except(dataset.DoubleVariables).Any())
+        throw new ArgumentException("All allowed input variables must be present in the dataset and of type double.");
+
+      var inputVariables = new CheckedItemList<StringValue>(dataset.DoubleVariables.Select(x => new StringValue(x)));
+      foreach (StringValue x in inputVariables)
+        inputVariables.SetItemCheckedState(x, allowedInputVariables.Contains(x.Value));
+
+      int trainingPartitionStart = 0;
+      int trainingPartitionEnd = dataset.Rows / 2;
+      int testPartitionStart = dataset.Rows / 2;
+      int testPartitionEnd = dataset.Rows;
+
+      Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", dataset));
+      Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, "", inputVariables.AsReadOnly()));
+      Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", new IntRange(trainingPartitionStart, trainingPartitionEnd)));
+      Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", new IntRange(testPartitionStart, testPartitionEnd)));
+
+      ((ValueParameter<Dataset>)DatasetParameter).ReactOnValueToStringChangedAndValueItemImageChanged = false;
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      DatasetParameter.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      InputVariables.CheckedItemsChanged += new CollectionItemsChangedEventHandler<IndexedItem<StringValue>>(InputVariables_CheckedItemsChanged);
+      TrainingPartition.ValueChanged += new EventHandler(Parameter_ValueChanged);
+      TestPartition.ValueChanged += new EventHandler(Parameter_ValueChanged);
+    }
+
+    private void InputVariables_CheckedItemsChanged(object sender, CollectionItemsChangedEventArgs<IndexedItem<StringValue>> e) {
+      OnChanged();
+    }
+
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+    public event EventHandler Changed;
+    protected virtual void OnChanged() {
+      var listeners = Changed;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/DataAnalysisSolution.cs	(revision 16097)
@@ -0,0 +1,168 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Drawing;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Abstract base class for data analysis solutions
+  /// </summary>
+  [StorableClass]
+  public abstract class DataAnalysisSolution : ResultCollection, IDataAnalysisSolution {
+    private const string ModelResultName = "Model";
+    private const string ProblemDataResultName = "ProblemData";
+
+    public string Filename { get; set; }
+
+    public static new Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.Function; }
+    }
+
+    #region properties
+    public IDataAnalysisModel Model {
+      get { return (IDataAnalysisModel)this[ModelResultName].Value; }
+      protected set {
+        if (this[ModelResultName].Value != value) {
+          if (value != null) {
+            this[ModelResultName].Value = value;
+            OnModelChanged();
+          }
+        }
+      }
+    }
+
+    public IDataAnalysisProblemData ProblemData {
+      get { return (IDataAnalysisProblemData)this[ProblemDataResultName].Value; }
+      set {
+        if (this[ProblemDataResultName].Value != value) {
+          if (value != null) {
+            ProblemData.Changed -= new EventHandler(ProblemData_Changed);
+            this[ProblemDataResultName].Value = value;
+            ProblemData.Changed += new EventHandler(ProblemData_Changed);
+            OnProblemDataChanged();
+          }
+        }
+      }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected DataAnalysisSolution(bool deserializing) : base(deserializing) { }
+    protected DataAnalysisSolution(DataAnalysisSolution original, Cloner cloner)
+      : base(original, cloner) {
+      name = original.Name;
+      description = original.Description;
+    }
+    public DataAnalysisSolution(IDataAnalysisModel model, IDataAnalysisProblemData problemData)
+      : base() {
+      name = ItemName;
+      description = ItemDescription;
+      Add(new Result(ModelResultName, "The data analysis model.", model));
+      Add(new Result(ProblemDataResultName, "The data analysis problem data.", problemData));
+
+      problemData.Changed += new EventHandler(ProblemData_Changed);
+    }
+
+    protected abstract void RecalculateResults();
+
+    private void ProblemData_Changed(object sender, EventArgs e) {
+      OnProblemDataChanged();
+    }
+
+    public event EventHandler ModelChanged;
+    protected virtual void OnModelChanged() {
+      RecalculateResults();
+      var listeners = ModelChanged;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+
+    public event EventHandler ProblemDataChanged;
+    protected virtual void OnProblemDataChanged() {
+      RecalculateResults();
+      var listeners = ProblemDataChanged;
+      if (listeners != null) listeners(this, EventArgs.Empty);
+    }
+
+    #region INamedItem Members
+    [Storable]
+    protected string name;
+    public string Name {
+      get { return name; }
+      set {
+        if (!CanChangeName) throw new NotSupportedException("Name cannot be changed.");
+        if (!(name.Equals(value) || (value == null) && (name == string.Empty))) {
+          CancelEventArgs<string> e = value == null ? new CancelEventArgs<string>(string.Empty) : new CancelEventArgs<string>(value);
+          OnNameChanging(e);
+          if (!e.Cancel) {
+            name = value == null ? string.Empty : value;
+            OnNameChanged();
+          }
+        }
+      }
+    }
+    public virtual bool CanChangeName {
+      get { return true; }
+    }
+    [Storable]
+    protected string description;
+    public string Description {
+      get { return description; }
+      set {
+        if (!CanChangeDescription) throw new NotSupportedException("Description cannot be changed.");
+        if (!(description.Equals(value) || (value == null) && (description == string.Empty))) {
+          description = value == null ? string.Empty : value;
+          OnDescriptionChanged();
+        }
+      }
+    }
+    public virtual bool CanChangeDescription {
+      get { return true; }
+    }
+
+    public override string ToString() {
+      return Name;
+    }
+
+    public event EventHandler<CancelEventArgs<string>> NameChanging;
+    protected virtual void OnNameChanging(CancelEventArgs<string> e) {
+      var handler = NameChanging;
+      if (handler != null) handler(this, e);
+    }
+
+    public event EventHandler NameChanged;
+    protected virtual void OnNameChanged() {
+      var handler = NameChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+      OnToStringChanged();
+    }
+
+    public event EventHandler DescriptionChanged;
+    protected virtual void OnDescriptionChanged() {
+      var handler = DescriptionChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionModel.cs	(revision 16097)
@@ -0,0 +1,60 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Item("Constant Regression Model", "A model that always returns the same constant value regardless of the presented input data.")]
+  public class ConstantRegressionModel : NamedItem, IRegressionModel {
+    [Storable]
+    protected double constant;
+    public double Constant {
+      get { return constant; }
+    }
+
+    [StorableConstructor]
+    protected ConstantRegressionModel(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionModel(ConstantRegressionModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.constant = original.constant;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new ConstantRegressionModel(this, cloner); }
+
+    public ConstantRegressionModel(double constant)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.constant = constant;
+    }
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      return rows.Select(row => Constant);
+    }
+
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new ConstantRegressionSolution(this, new RegressionProblemData(problemData));
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/ConstantRegressionSolution.cs	(revision 16097)
@@ -0,0 +1,26 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item(Name = "Constant Regression Solution", Description = "Represents a constant regression solution (model + data).")]
+  public class ConstantRegressionSolution : RegressionSolution {
+    public new ConstantRegressionModel Model {
+      get { return (ConstantRegressionModel)base.Model; }
+      set { base.Model = value; }
+    }
+
+    [StorableConstructor]
+    protected ConstantRegressionSolution(bool deserializing) : base(deserializing) { }
+    protected ConstantRegressionSolution(ConstantRegressionSolution original, Cloner cloner) : base(original, cloner) { }
+    public ConstantRegressionSolution(ConstantRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      RecalculateResults();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantRegressionSolution(this, cloner);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleModel.cs	(revision 16097)
@@ -0,0 +1,112 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents regression solutions that contain an ensemble of multiple regression models
+  /// </summary>
+  [StorableClass]
+  [Item("RegressionEnsembleModel", "A regression model that contains an ensemble of multiple regression models")]
+  public class RegressionEnsembleModel : NamedItem, IRegressionEnsembleModel {
+
+    private List<IRegressionModel> models;
+    public IEnumerable<IRegressionModel> Models {
+      get { return new List<IRegressionModel>(models); }
+    }
+
+    [Storable(Name = "Models")]
+    private IEnumerable<IRegressionModel> StorableModels {
+      get { return models; }
+      set { models = value.ToList(); }
+    }
+
+    #region backwards compatiblity 3.3.5
+    [Storable(Name = "models", AllowOneWay = true)]
+    private List<IRegressionModel> OldStorableModels {
+      set { models = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected RegressionEnsembleModel(bool deserializing) : base(deserializing) { }
+    protected RegressionEnsembleModel(RegressionEnsembleModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.models = original.Models.Select(m => cloner.Clone(m)).ToList();
+    }
+
+    public RegressionEnsembleModel() : this(Enumerable.Empty<IRegressionModel>()) { }
+    public RegressionEnsembleModel(IEnumerable<IRegressionModel> models)
+      : base() {
+      this.name = ItemName;
+      this.description = ItemDescription;
+      this.models = new List<IRegressionModel>(models);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionEnsembleModel(this, cloner);
+    }
+
+    #region IRegressionEnsembleModel Members
+
+    public void Add(IRegressionModel model) {
+      models.Add(model);
+    }
+    public void Remove(IRegressionModel model) {
+      models.Remove(model);
+    }
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      var estimatedValuesEnumerators = (from model in models
+                                        select model.GetEstimatedValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    #endregion
+
+    #region IRegressionModel Members
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      foreach (var estimatedValuesVector in GetEstimatedValueVectors(dataset, rows)) {
+        yield return estimatedValuesVector.Average();
+      }
+    }
+
+    public RegressionEnsembleSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      return new RegressionEnsembleSolution(this.Models, new RegressionEnsembleProblemData(problemData));
+    }
+    IRegressionSolution IRegressionModel.CreateRegressionSolution(IRegressionProblemData problemData) {
+      return CreateRegressionSolution(problemData);
+    }
+
+    #endregion
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleProblemData.cs	(revision 16097)
@@ -0,0 +1,83 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("RegressionEnsembleProblemData", "Represents an item containing all data defining a regression problem.")]
+  public sealed class RegressionEnsembleProblemData : RegressionProblemData {
+
+    public override bool IsTrainingSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+             TrainingPartition.Start <= index && index < TrainingPartition.End;
+    }
+
+    public override bool IsTestSample(int index) {
+      return index >= 0 && index < Dataset.Rows &&
+             TestPartition.Start <= index && index < TestPartition.End;
+    }
+
+    private static readonly RegressionEnsembleProblemData emptyProblemData;
+    public new static RegressionEnsembleProblemData EmptyProblemData {
+      get { return emptyProblemData; }
+    }
+    static RegressionEnsembleProblemData() {
+      var problemData = new RegressionEnsembleProblemData();
+      problemData.Parameters.Clear();
+      problemData.Name = "Empty Regression ProblemData";
+      problemData.Description = "This ProblemData acts as place holder before the correct problem data is loaded.";
+      problemData.isEmpty = true;
+
+      problemData.Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", new Dataset()));
+      problemData.Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, ""));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
+      emptyProblemData = problemData;
+    }
+
+    [StorableConstructor]
+    private RegressionEnsembleProblemData(bool deserializing) : base(deserializing) { }
+    private RegressionEnsembleProblemData(RegressionEnsembleProblemData original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (this == emptyProblemData) return emptyProblemData;
+      return new RegressionEnsembleProblemData(this, cloner);
+    }
+
+    public RegressionEnsembleProblemData() : base() { }
+    public RegressionEnsembleProblemData(IRegressionProblemData regressionProblemData)
+      : base(regressionProblemData.Dataset, regressionProblemData.AllowedInputVariables, regressionProblemData.TargetVariable) {
+      TrainingPartition.Start = regressionProblemData.TrainingPartition.Start;
+      TrainingPartition.End = regressionProblemData.TrainingPartition.End;
+      TestPartition.Start = regressionProblemData.TestPartition.Start;
+      TestPartition.End = regressionProblemData.TestPartition.End;
+    }
+    public RegressionEnsembleProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables, targetVariable) {
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionEnsembleSolution.cs	(revision 16097)
@@ -0,0 +1,332 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents regression solutions that contain an ensemble of multiple regression models
+  /// </summary>
+  [StorableClass]
+  [Item("Regression Ensemble Solution", "A regression solution that contains an ensemble of multiple regression models")]
+  [Creatable("Data Analysis - Ensembles")]
+  public sealed class RegressionEnsembleSolution : RegressionSolutionBase, IRegressionEnsembleSolution {
+    private readonly Dictionary<int, double> trainingEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> testEvaluationCache = new Dictionary<int, double>();
+    private readonly Dictionary<int, double> evaluationCache = new Dictionary<int, double>();
+
+    public new IRegressionEnsembleModel Model {
+      get { return (IRegressionEnsembleModel)base.Model; }
+    }
+
+    public new RegressionEnsembleProblemData ProblemData {
+      get { return (RegressionEnsembleProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    private readonly ItemCollection<IRegressionSolution> regressionSolutions;
+    public IItemCollection<IRegressionSolution> RegressionSolutions {
+      get { return regressionSolutions; }
+    }
+
+    [Storable]
+    private readonly Dictionary<IRegressionModel, IntRange> trainingPartitions;
+    [Storable]
+    private readonly Dictionary<IRegressionModel, IntRange> testPartitions;
+
+    [StorableConstructor]
+    private RegressionEnsembleSolution(bool deserializing)
+      : base(deserializing) {
+      regressionSolutions = new ItemCollection<IRegressionSolution>();
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      foreach (var model in Model.Models) {
+        IRegressionProblemData problemData = (IRegressionProblemData)ProblemData.Clone();
+        problemData.TrainingPartition.Start = trainingPartitions[model].Start;
+        problemData.TrainingPartition.End = trainingPartitions[model].End;
+        problemData.TestPartition.Start = testPartitions[model].Start;
+        problemData.TestPartition.End = testPartitions[model].End;
+
+        regressionSolutions.Add(model.CreateRegressionSolution(problemData));
+      }
+      RegisterRegressionSolutionsEventHandler();
+    }
+
+    private RegressionEnsembleSolution(RegressionEnsembleSolution original, Cloner cloner)
+      : base(original, cloner) {
+      trainingPartitions = new Dictionary<IRegressionModel, IntRange>();
+      testPartitions = new Dictionary<IRegressionModel, IntRange>();
+      foreach (var pair in original.trainingPartitions) {
+        trainingPartitions[cloner.Clone(pair.Key)] = cloner.Clone(pair.Value);
+      }
+      foreach (var pair in original.testPartitions) {
+        testPartitions[cloner.Clone(pair.Key)] = cloner.Clone(pair.Value);
+      }
+
+      trainingEvaluationCache = new Dictionary<int, double>(original.ProblemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(original.ProblemData.TestIndices.Count());
+
+      regressionSolutions = cloner.Clone(original.regressionSolutions);
+      RegisterRegressionSolutionsEventHandler();
+    }
+
+    public RegressionEnsembleSolution()
+      : base(new RegressionEnsembleModel(), RegressionEnsembleProblemData.EmptyProblemData) {
+      trainingPartitions = new Dictionary<IRegressionModel, IntRange>();
+      testPartitions = new Dictionary<IRegressionModel, IntRange>();
+      regressionSolutions = new ItemCollection<IRegressionSolution>();
+
+      RegisterRegressionSolutionsEventHandler();
+    }
+
+    public RegressionEnsembleSolution(IRegressionProblemData problemData)
+      : this(Enumerable.Empty<IRegressionModel>(), problemData) {
+    }
+
+    public RegressionEnsembleSolution(IEnumerable<IRegressionModel> models, IRegressionProblemData problemData)
+      : this(models, problemData,
+             models.Select(m => (IntRange)problemData.TrainingPartition.Clone()),
+             models.Select(m => (IntRange)problemData.TestPartition.Clone())
+      ) { }
+
+    public RegressionEnsembleSolution(IEnumerable<IRegressionModel> models, IRegressionProblemData problemData, IEnumerable<IntRange> trainingPartitions, IEnumerable<IntRange> testPartitions)
+      : base(new RegressionEnsembleModel(Enumerable.Empty<IRegressionModel>()), new RegressionEnsembleProblemData(problemData)) {
+      this.trainingPartitions = new Dictionary<IRegressionModel, IntRange>();
+      this.testPartitions = new Dictionary<IRegressionModel, IntRange>();
+      this.regressionSolutions = new ItemCollection<IRegressionSolution>();
+
+      List<IRegressionSolution> solutions = new List<IRegressionSolution>();
+      var modelEnumerator = models.GetEnumerator();
+      var trainingPartitionEnumerator = trainingPartitions.GetEnumerator();
+      var testPartitionEnumerator = testPartitions.GetEnumerator();
+
+      while (modelEnumerator.MoveNext() & trainingPartitionEnumerator.MoveNext() & testPartitionEnumerator.MoveNext()) {
+        var p = (IRegressionProblemData)problemData.Clone();
+        p.TrainingPartition.Start = trainingPartitionEnumerator.Current.Start;
+        p.TrainingPartition.End = trainingPartitionEnumerator.Current.End;
+        p.TestPartition.Start = testPartitionEnumerator.Current.Start;
+        p.TestPartition.End = testPartitionEnumerator.Current.End;
+
+        solutions.Add(modelEnumerator.Current.CreateRegressionSolution(p));
+      }
+      if (modelEnumerator.MoveNext() | trainingPartitionEnumerator.MoveNext() | testPartitionEnumerator.MoveNext()) {
+        throw new ArgumentException();
+      }
+
+      trainingEvaluationCache = new Dictionary<int, double>(problemData.TrainingIndices.Count());
+      testEvaluationCache = new Dictionary<int, double>(problemData.TestIndices.Count());
+
+      RegisterRegressionSolutionsEventHandler();
+      regressionSolutions.AddRange(solutions);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RegressionEnsembleSolution(this, cloner);
+    }
+    private void RegisterRegressionSolutionsEventHandler() {
+      regressionSolutions.ItemsAdded += new CollectionItemsChangedEventHandler<IRegressionSolution>(regressionSolutions_ItemsAdded);
+      regressionSolutions.ItemsRemoved += new CollectionItemsChangedEventHandler<IRegressionSolution>(regressionSolutions_ItemsRemoved);
+      regressionSolutions.CollectionReset += new CollectionItemsChangedEventHandler<IRegressionSolution>(regressionSolutions_CollectionReset);
+    }
+
+    #region Evaluation
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get {
+        var rows = ProblemData.TrainingIndices;
+        var rowsToEvaluate = rows.Except(trainingEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, (r, m) => RowIsTrainingForModel(r, m) && !RowIsTestForModel(r, m)).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          trainingEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+        }
+
+        return rows.Select(row => trainingEvaluationCache[row]);
+      }
+    }
+
+    public override IEnumerable<double> EstimatedTestValues {
+      get {
+        var rows = ProblemData.TestIndices;
+        var rowsToEvaluate = rows.Except(testEvaluationCache.Keys);
+        var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+        var valuesEnumerator = GetEstimatedValues(rowsToEvaluate, RowIsTestForModel).GetEnumerator();
+
+        while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+          testEvaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+        }
+
+        return rows.Select(row => testEvaluationCache[row]);
+      }
+    }
+
+    private IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows, Func<int, IRegressionModel, bool> modelSelectionPredicate) {
+      var estimatedValuesEnumerators = (from model in Model.Models
+                                        select new { Model = model, EstimatedValuesEnumerator = model.GetEstimatedValues(ProblemData.Dataset, rows).GetEnumerator() })
+                                       .ToList();
+      var rowsEnumerator = rows.GetEnumerator();
+      // aggregate to make sure that MoveNext is called for all enumerators 
+      while (rowsEnumerator.MoveNext() & estimatedValuesEnumerators.Select(en => en.EstimatedValuesEnumerator.MoveNext()).Aggregate(true, (acc, b) => acc & b)) {
+        int currentRow = rowsEnumerator.Current;
+
+        var selectedEnumerators = from pair in estimatedValuesEnumerators
+                                  where modelSelectionPredicate(currentRow, pair.Model)
+                                  select pair.EstimatedValuesEnumerator;
+
+        yield return AggregateEstimatedValues(selectedEnumerators.Select(x => x.Current));
+      }
+    }
+
+    private bool RowIsTrainingForModel(int currentRow, IRegressionModel model) {
+      return trainingPartitions == null || !trainingPartitions.ContainsKey(model) ||
+              (trainingPartitions[model].Start <= currentRow && currentRow < trainingPartitions[model].End);
+    }
+
+    private bool RowIsTestForModel(int currentRow, IRegressionModel model) {
+      return testPartitions == null || !testPartitions.ContainsKey(model) ||
+              (testPartitions[model].Start <= currentRow && currentRow < testPartitions[model].End);
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = (from xs in GetEstimatedValueVectors(ProblemData.Dataset, rowsToEvaluate)
+                              select AggregateEstimatedValues(xs))
+                             .GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
+    }
+
+    public IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows) {
+      if (!Model.Models.Any()) yield break;
+      var estimatedValuesEnumerators = (from model in Model.Models
+                                        select model.GetEstimatedValues(dataset, rows).GetEnumerator())
+                                       .ToList();
+
+      while (estimatedValuesEnumerators.All(en => en.MoveNext())) {
+        yield return from enumerator in estimatedValuesEnumerators
+                     select enumerator.Current;
+      }
+    }
+
+    private double AggregateEstimatedValues(IEnumerable<double> estimatedValues) {
+      return estimatedValues.DefaultIfEmpty(double.NaN).Average();
+    }
+    #endregion
+
+    protected override void OnProblemDataChanged() {
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+      IRegressionProblemData problemData = new RegressionProblemData(ProblemData.Dataset,
+                                                                     ProblemData.AllowedInputVariables,
+                                                                     ProblemData.TargetVariable);
+      problemData.TrainingPartition.Start = ProblemData.TrainingPartition.Start;
+      problemData.TrainingPartition.End = ProblemData.TrainingPartition.End;
+      problemData.TestPartition.Start = ProblemData.TestPartition.Start;
+      problemData.TestPartition.End = ProblemData.TestPartition.End;
+
+      foreach (var solution in RegressionSolutions) {
+        if (solution is RegressionEnsembleSolution)
+          solution.ProblemData = ProblemData;
+        else
+          solution.ProblemData = problemData;
+      }
+      foreach (var trainingPartition in trainingPartitions.Values) {
+        trainingPartition.Start = ProblemData.TrainingPartition.Start;
+        trainingPartition.End = ProblemData.TrainingPartition.End;
+      }
+      foreach (var testPartition in testPartitions.Values) {
+        testPartition.Start = ProblemData.TestPartition.Start;
+        testPartition.End = ProblemData.TestPartition.End;
+      }
+
+      base.OnProblemDataChanged();
+    }
+
+    public void AddRegressionSolutions(IEnumerable<IRegressionSolution> solutions) {
+      regressionSolutions.AddRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+    }
+    public void RemoveRegressionSolutions(IEnumerable<IRegressionSolution> solutions) {
+      regressionSolutions.RemoveRange(solutions);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+    }
+
+    private void regressionSolutions_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IRegressionSolution> e) {
+      foreach (var solution in e.Items) AddRegressionSolution(solution);
+      RecalculateResults();
+    }
+    private void regressionSolutions_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IRegressionSolution> e) {
+      foreach (var solution in e.Items) RemoveRegressionSolution(solution);
+      RecalculateResults();
+    }
+    private void regressionSolutions_CollectionReset(object sender, CollectionItemsChangedEventArgs<IRegressionSolution> e) {
+      foreach (var solution in e.OldItems) RemoveRegressionSolution(solution);
+      foreach (var solution in e.Items) AddRegressionSolution(solution);
+      RecalculateResults();
+    }
+
+    private void AddRegressionSolution(IRegressionSolution solution) {
+      if (Model.Models.Contains(solution.Model)) throw new ArgumentException();
+      Model.Add(solution.Model);
+      trainingPartitions[solution.Model] = solution.ProblemData.TrainingPartition;
+      testPartitions[solution.Model] = solution.ProblemData.TestPartition;
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+    }
+
+    private void RemoveRegressionSolution(IRegressionSolution solution) {
+      if (!Model.Models.Contains(solution.Model)) throw new ArgumentException();
+      Model.Remove(solution.Model);
+      trainingPartitions.Remove(solution.Model);
+      testPartitions.Remove(solution.Model);
+
+      trainingEvaluationCache.Clear();
+      testEvaluationCache.Clear();
+      evaluationCache.Clear();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblem.cs	(revision 16097)
@@ -0,0 +1,41 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Regression Problem", "A general regression problem.")]
+  [Creatable("Problems")]
+  public class RegressionProblem : DataAnalysisProblem<IRegressionProblemData>, IRegressionProblem, IStorableContent {
+    public string Filename { get; set; }
+
+    [StorableConstructor]
+    protected RegressionProblem(bool deserializing) : base(deserializing) { }
+    protected RegressionProblem(RegressionProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new RegressionProblem(this, cloner); }
+
+    public RegressionProblem() : base(new RegressionProblemData()) { }
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionProblemData.cs	(revision 16097)
@@ -0,0 +1,145 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("RegressionProblemData", "Represents an item containing all data defining a regression problem.")]
+  public class RegressionProblemData : DataAnalysisProblemData, IRegressionProblemData, IStorableContent {
+    protected const string TargetVariableParameterName = "TargetVariable";
+    public string Filename { get; set; }
+
+    #region default data
+    private static double[,] kozaF1 = new double[,] {
+          {2.017885919,	-1.449165046},
+          {1.30060506,	-1.344523885},
+          {1.147134798,	-1.317989331},
+          {0.877182504,	-1.266142284},
+          {0.852562452,	-1.261020794},
+          {0.431095788,	-1.158793317},
+          {0.112586002,	-1.050908405},
+          {0.04594507,	-1.021989402},
+          {0.042572879,	-1.020438113},
+          {-0.074027291,	-0.959859562},
+          {-0.109178553,	-0.938094706},
+          {-0.259721109,	-0.803635355},
+          {-0.272991057,	-0.387519561},
+          {-0.161978191,	-0.193611001},
+          {-0.102489983,	-0.114215349},
+          {-0.01469968,	-0.014918985},
+          {-0.008863365,	-0.008942626},
+          {0.026751057,	0.026054094},
+          {0.166922436,	0.14309643},
+          {0.176953808,	0.1504144},
+          {0.190233418,	0.159916534},
+          {0.199800708,	0.166635331},
+          {0.261502822,	0.207600348},
+          {0.30182879,	0.232370249},
+          {0.83763905,	0.468046718}
+    };
+    private static readonly Dataset defaultDataset;
+    private static readonly IEnumerable<string> defaultAllowedInputVariables;
+    private static readonly string defaultTargetVariable;
+
+    private static readonly RegressionProblemData emptyProblemData;
+    public static RegressionProblemData EmptyProblemData {
+      get { return emptyProblemData; }
+    }
+
+    static RegressionProblemData() {
+      defaultDataset = new Dataset(new string[] { "y", "x" }, kozaF1);
+      defaultDataset.Name = "Fourth-order Polynomial Function Benchmark Dataset";
+      defaultDataset.Description = "f(x) = x^4 + x^3 + x^2 + x^1";
+      defaultAllowedInputVariables = new List<string>() { "x" };
+      defaultTargetVariable = "y";
+
+      var problemData = new RegressionProblemData();
+      problemData.Parameters.Clear();
+      problemData.Name = "Empty Regression ProblemData";
+      problemData.Description = "This ProblemData acts as place holder before the correct problem data is loaded.";
+      problemData.isEmpty = true;
+
+      problemData.Parameters.Add(new FixedValueParameter<Dataset>(DatasetParameterName, "", new Dataset()));
+      problemData.Parameters.Add(new FixedValueParameter<ReadOnlyCheckedItemList<StringValue>>(InputVariablesParameterName, ""));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TrainingPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new FixedValueParameter<IntRange>(TestPartitionParameterName, "", (IntRange)new IntRange(0, 0).AsReadOnly()));
+      problemData.Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>()));
+      emptyProblemData = problemData;
+    }
+    #endregion
+
+    public IConstrainedValueParameter<StringValue> TargetVariableParameter {
+      get { return (IConstrainedValueParameter<StringValue>)Parameters[TargetVariableParameterName]; }
+    }
+    public string TargetVariable {
+      get { return TargetVariableParameter.Value.Value; }
+    }
+
+    [StorableConstructor]
+    protected RegressionProblemData(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+
+    protected RegressionProblemData(RegressionProblemData original, Cloner cloner)
+      : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      if (this == emptyProblemData) return emptyProblemData;
+      return new RegressionProblemData(this, cloner);
+    }
+
+    public RegressionProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
+    }
+    public RegressionProblemData(IRegressionProblemData regressionProblemData)
+      : this(regressionProblemData.Dataset, regressionProblemData.AllowedInputVariables, regressionProblemData.TargetVariable) {
+      TrainingPartition.Start = regressionProblemData.TrainingPartition.Start;
+      TrainingPartition.End = regressionProblemData.TrainingPartition.End;
+      TestPartition.Start = regressionProblemData.TestPartition.Start;
+      TestPartition.End = regressionProblemData.TestPartition.End;
+    }
+
+    public RegressionProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables) {
+      var variables = InputVariables.Select(x => x.AsReadOnly()).ToList();
+      Parameters.Add(new ConstrainedValueParameter<StringValue>(TargetVariableParameterName, new ItemSet<StringValue>(variables), variables.Where(x => x.Value == targetVariable).First()));
+      RegisterParameterEvents();
+    }
+
+    private void RegisterParameterEvents() {
+      TargetVariableParameter.ValueChanged += new EventHandler(TargetVariableParameter_ValueChanged);
+    }
+    private void TargetVariableParameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolution.cs	(revision 16097)
@@ -0,0 +1,83 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a regression data analysis solution
+  /// </summary>
+  [StorableClass]
+  public abstract class RegressionSolution : RegressionSolutionBase {
+    protected readonly Dictionary<int, double> evaluationCache;
+
+    [StorableConstructor]
+    protected RegressionSolution(bool deserializing)
+      : base(deserializing) {
+      evaluationCache = new Dictionary<int, double>();
+    }
+    protected RegressionSolution(RegressionSolution original, Cloner cloner)
+      : base(original, cloner) {
+      evaluationCache = new Dictionary<int, double>(original.evaluationCache);
+    }
+    protected RegressionSolution(IRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      evaluationCache = new Dictionary<int, double>(problemData.Dataset.Rows);
+      CalculateRegressionResults();
+    }
+
+
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
+    }
+
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      var rowsToEvaluate = rows.Except(evaluationCache.Keys);
+      var rowsEnumerator = rowsToEvaluate.GetEnumerator();
+      var valuesEnumerator = Model.GetEstimatedValues(ProblemData.Dataset, rowsToEvaluate).GetEnumerator();
+
+      while (rowsEnumerator.MoveNext() & valuesEnumerator.MoveNext()) {
+        evaluationCache.Add(rowsEnumerator.Current, valuesEnumerator.Current);
+      }
+
+      return rows.Select(row => evaluationCache[row]);
+    }
+
+    protected override void OnProblemDataChanged() {
+      evaluationCache.Clear();
+      base.OnProblemDataChanged();
+    }
+
+    protected override void OnModelChanged() {
+      evaluationCache.Clear();
+      base.OnModelChanged();
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/Regression/RegressionSolutionBase.cs	(revision 16097)
@@ -0,0 +1,221 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class RegressionSolutionBase : DataAnalysisSolution, IRegressionSolution {
+    protected const string TrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    protected const string TestMeanSquaredErrorResultName = "Mean squared error (test)";
+    protected const string TrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    protected const string TestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+    protected const string TrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    protected const string TestSquaredCorrelationResultName = "Pearson's R² (test)";
+    protected const string TrainingRelativeErrorResultName = "Average relative error (training)";
+    protected const string TestRelativeErrorResultName = "Average relative error (test)";
+    protected const string TrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+    protected const string TestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+    protected const string TrainingMeanErrorResultName = "Mean error (training)";
+    protected const string TestMeanErrorResultName = "Mean error (test)";
+
+    protected const string TrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
+    protected const string TestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
+    protected const string TrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
+    protected const string TestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
+    protected const string TrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
+    protected const string TestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
+    protected const string TrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
+    protected const string TestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
+    protected const string TrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
+    protected const string TestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
+    protected const string TrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
+    protected const string TestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
+
+    public new IRegressionModel Model {
+      get { return (IRegressionModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new IRegressionProblemData ProblemData {
+      get { return (IRegressionProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public abstract IEnumerable<double> EstimatedValues { get; }
+    public abstract IEnumerable<double> EstimatedTrainingValues { get; }
+    public abstract IEnumerable<double> EstimatedTestValues { get; }
+    public abstract IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+
+    #region Results
+    public double TrainingMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanSquaredError {
+      get { return ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingMeanAbsoluteError {
+      get { return ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanAbsoluteErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanAbsoluteError {
+      get { return ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanAbsoluteErrorResultName].Value).Value = value; }
+    }
+    public double TrainingRSquared {
+      get { return ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingSquaredCorrelationResultName].Value).Value = value; }
+    }
+    public double TestRSquared {
+      get { return ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestSquaredCorrelationResultName].Value).Value = value; }
+    }
+    public double TrainingRelativeError {
+      get { return ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingRelativeErrorResultName].Value).Value = value; }
+    }
+    public double TestRelativeError {
+      get { return ((DoubleValue)this[TestRelativeErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestRelativeErrorResultName].Value).Value = value; }
+    }
+    public double TrainingNormalizedMeanSquaredError {
+      get { return ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TestNormalizedMeanSquaredError {
+      get { return ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestNormalizedMeanSquaredErrorResultName].Value).Value = value; }
+    }
+    public double TrainingMeanError {
+      get { return ((DoubleValue)this[TrainingMeanErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingMeanErrorResultName].Value).Value = value; }
+    }
+    public double TestMeanError {
+      get { return ((DoubleValue)this[TestMeanErrorResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestMeanErrorResultName].Value).Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected RegressionSolutionBase(bool deserializing) : base(deserializing) { }
+    protected RegressionSolutionBase(RegressionSolutionBase original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    protected RegressionSolutionBase(IRegressionModel model, IRegressionProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingMeanSquaredErrorResultName, TrainingMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanSquaredErrorResultName, TestMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingMeanAbsoluteErrorResultName, TrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanAbsoluteErrorResultName, TestMeanAbsoluteErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingSquaredCorrelationResultName, TrainingSquaredCorrelationResultDescription, new DoubleValue()));
+      Add(new Result(TestSquaredCorrelationResultName, TestSquaredCorrelationResultDescription, new DoubleValue()));
+      Add(new Result(TrainingRelativeErrorResultName, TrainingRelativeErrorResultDescription, new PercentValue()));
+      Add(new Result(TestRelativeErrorResultName, TestRelativeErrorResultDescription, new PercentValue()));
+      Add(new Result(TrainingNormalizedMeanSquaredErrorResultName, TrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestNormalizedMeanSquaredErrorResultName, TestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+      Add(new Result(TrainingMeanErrorResultName, TrainingMeanErrorResultDescription, new DoubleValue()));
+      Add(new Result(TestMeanErrorResultName, TestMeanErrorResultDescription, new DoubleValue()));
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      // BackwardsCompatibility3.4
+
+      #region Backwards compatible code, remove with 3.5
+
+      if (!ContainsKey(TrainingMeanAbsoluteErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TrainingMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the training partition", new DoubleValue()));
+        double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
+        TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      }
+
+      if (!ContainsKey(TestMeanAbsoluteErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TestMeanAbsoluteErrorResultName, "Mean of absolute errors of the model on the test partition", new DoubleValue()));
+        double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
+        TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+      }
+
+      if (!ContainsKey(TrainingMeanErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TrainingMeanErrorResultName, "Mean of errors of the model on the training partition", new DoubleValue()));
+        double trainingME = OnlineMeanErrorCalculator.Calculate(EstimatedTrainingValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices), out errorState);
+        TrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+      }
+      if (!ContainsKey(TestMeanErrorResultName)) {
+        OnlineCalculatorError errorState;
+        Add(new Result(TestMeanErrorResultName, "Mean of errors of the model on the test partition", new DoubleValue()));
+        double testME = OnlineMeanErrorCalculator.Calculate(EstimatedTestValues, ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices), out errorState);
+        TestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+      }
+      #endregion
+    }
+
+    protected override void RecalculateResults() {
+      CalculateRegressionResults();
+    }
+
+    protected void CalculateRegressionResults() {
+      IEnumerable<double> estimatedTrainingValues = EstimatedTrainingValues; // cache values
+      IEnumerable<double> originalTrainingValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices);
+      IEnumerable<double> estimatedTestValues = EstimatedTestValues; // cache values
+      IEnumerable<double> originalTestValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices);
+
+      OnlineCalculatorError errorState;
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+
+      double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      TrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+      double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      TestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/ConstantTimeSeriesPrognosisModel.cs	(revision 16097)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Constant TimeSeries Model", "A time series model that returns for all prediciton the same constant value.")]
+  public class ConstantTimeSeriesPrognosisModel : ConstantRegressionModel, ITimeSeriesPrognosisModel {
+    [StorableConstructor]
+    protected ConstantTimeSeriesPrognosisModel(bool deserializing) : base(deserializing) { }
+    protected ConstantTimeSeriesPrognosisModel(ConstantTimeSeriesPrognosisModel original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ConstantTimeSeriesPrognosisModel(this, cloner);
+    }
+
+    public ConstantTimeSeriesPrognosisModel(double constant) : base(constant) { }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return horizons.Select(horizon => Enumerable.Repeat(Constant, horizon));
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, new TimeSeriesPrognosisProblemData(problemData));
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/Models/TimeSeriesPrognosisAutoRegressiveModel.cs	(revision 16097)
@@ -0,0 +1,118 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Autoregressive TimeSeries Model", "A linear autoregressive time series model used to predict future values.")]
+  public class TimeSeriesPrognosisAutoRegressiveModel : NamedItem, ITimeSeriesPrognosisModel {
+    [Storable]
+    public double[] Phi { get; private set; }
+    [Storable]
+    public double Constant { get; private set; }
+    [Storable]
+    public string TargetVariable { get; private set; }
+
+    public int TimeOffset { get { return Phi.Length; } }
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisAutoRegressiveModel(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisAutoRegressiveModel(TimeSeriesPrognosisAutoRegressiveModel original, Cloner cloner)
+      : base(original, cloner) {
+      this.Phi = (double[])original.Phi.Clone();
+      this.Constant = original.Constant;
+      this.TargetVariable = original.TargetVariable;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisAutoRegressiveModel(this, cloner);
+    }
+    public TimeSeriesPrognosisAutoRegressiveModel(string targetVariable, double[] phi, double constant)
+      : base("AR(1) Model") {
+      Phi = (double[])phi.Clone();
+      Constant = constant;
+      TargetVariable = targetVariable;
+    }
+
+    public IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons) {
+      var rowsEnumerator = rows.GetEnumerator();
+      var horizonsEnumerator = horizons.GetEnumerator();
+      var targetValues = dataset.GetReadOnlyDoubleValues(TargetVariable);
+      // produce a n-step forecast for all rows
+      while (rowsEnumerator.MoveNext() & horizonsEnumerator.MoveNext()) {
+        int row = rowsEnumerator.Current;
+        int horizon = horizonsEnumerator.Current;
+        if (row - TimeOffset < 0) {
+          yield return Enumerable.Repeat(double.NaN, horizon);
+          continue;
+        }
+
+        double[] prognosis = new double[horizon];
+        for (int h = 0; h < horizon; h++) {
+          double estimatedValue = 0.0;
+          for (int i = 1; i <= TimeOffset; i++) {
+            int offset = h - i;
+            if (offset >= 0) estimatedValue += prognosis[offset] * Phi[i - 1];
+            else estimatedValue += targetValues[row + offset] * Phi[i - 1];
+
+          }
+          estimatedValue += Constant;
+          prognosis[h] = estimatedValue;
+        }
+
+        yield return prognosis;
+      }
+
+      if (rowsEnumerator.MoveNext() || horizonsEnumerator.MoveNext())
+        throw new ArgumentException("Number of elements in rows and horizon enumerations doesn't match.");
+    }
+
+    public IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows) {
+      var targetVariables = dataset.GetReadOnlyDoubleValues(TargetVariable);
+      foreach (int row in rows) {
+        double estimatedValue = 0.0;
+        if (row - TimeOffset < 0) {
+          yield return double.NaN;
+          continue;
+        }
+
+        for (int i = 1; i <= TimeOffset; i++) {
+          estimatedValue += targetVariables[row - i] * Phi[i - 1];
+        }
+        estimatedValue += Constant;
+        yield return estimatedValue;
+      }
+    }
+
+    public ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData) {
+      return new TimeSeriesPrognosisSolution(this, new TimeSeriesPrognosisProblemData(problemData));
+    }
+    public IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData) {
+      throw new NotSupportedException();
+    }
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblem.cs	(revision 16097)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Time-series Prognosis Problem", "A general time-series prognosis problem.")]
+  [Creatable("Problems")]
+  public class TimeSeriesPrognosisProblem : DataAnalysisProblem<ITimeSeriesPrognosisProblemData>, ITimeSeriesPrognosisProblem {
+    [StorableConstructor]
+    protected TimeSeriesPrognosisProblem(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisProblem(TimeSeriesPrognosisProblem original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) { return new TimeSeriesPrognosisProblem(this, cloner); }
+
+    public TimeSeriesPrognosisProblem() : base(new TimeSeriesPrognosisProblemData()) { }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisProblemData.cs	(revision 16097)
@@ -0,0 +1,1619 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+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 {
+  [StorableClass]
+  [Item("TimeSeriesPrognosisProblemData", "Represents an item containing all data defining a time series prognosis problem.")]
+  public class TimeSeriesPrognosisProblemData : RegressionProblemData, ITimeSeriesPrognosisProblemData {
+    #region default data
+    private static double[,] mackey_glass_17 = new double[,] {
+{9.0000000e-01},
+{9.0000000e-01},
+{9.0000000e-01},
+{9.4136145e-01},
+{1.1188041e+00},
+{1.2161867e+00},
+{1.2476827e+00},
+{1.0067861e+00},
+{7.1297054e-01},
+{5.0349420e-01},
+{5.8392542e-01},
+{9.4327347e-01},
+{1.0178784e+00},
+{1.0346794e+00},
+{1.1640420e+00},
+{1.0670009e+00},
+{1.0026658e+00},
+{7.7000347e-01},
+{7.0782984e-01},
+{7.9370192e-01},
+{1.0558440e+00},
+{1.2000510e+00},
+{1.2998549e+00},
+{1.1857500e+00},
+{8.4250325e-01},
+{5.5885374e-01},
+{4.2572016e-01},
+{7.5043060e-01},
+{9.7291951e-01},
+{9.3785503e-01},
+{1.0653587e+00},
+{1.1355961e+00},
+{1.1533842e+00},
+{1.0678134e+00},
+{8.1349649e-01},
+{6.6246660e-01},
+{6.2210481e-01},
+{9.3890430e-01},
+{1.1287058e+00},
+{1.1699535e+00},
+{1.2412759e+00},
+{9.8090748e-01},
+{7.3311051e-01},
+{5.2596003e-01},
+{6.3134850e-01},
+{9.7849655e-01},
+{1.0578901e+00},
+{1.0888001e+00},
+{1.1681297e+00},
+{9.9896471e-01},
+{8.7928027e-01},
+{6.6864116e-01},
+{7.3694626e-01},
+{9.7850487e-01},
+{1.1571565e+00},
+{1.2440406e+00},
+{1.2532851e+00},
+{9.3967388e-01},
+{6.5403177e-01},
+{4.5549437e-01},
+{6.4110939e-01},
+{9.6727507e-01},
+{9.8419122e-01},
+{1.0332443e+00},
+{1.1440570e+00},
+{1.0922307e+00},
+{1.0485820e+00},
+{8.0447560e-01},
+{7.1465526e-01},
+{7.1296010e-01},
+{9.9300973e-01},
+{1.1766813e+00},
+{1.2618288e+00},
+{1.2517022e+00},
+{9.2078170e-01},
+{6.2369710e-01},
+{4.3562308e-01},
+{6.4988558e-01},
+{9.5895791e-01},
+{9.5866122e-01},
+{1.0183775e+00},
+{1.1415533e+00},
+{1.1289579e+00},
+{1.1022163e+00},
+{8.4414928e-01},
+{6.9891813e-01},
+{6.2493643e-01},
+{9.0049230e-01},
+{1.1246569e+00},
+{1.1850486e+00},
+{1.2646400e+00},
+{1.0193893e+00},
+{7.3830722e-01},
+{5.1921750e-01},
+{5.6836076e-01},
+{9.3609361e-01},
+{1.0324202e+00},
+{1.0360676e+00},
+{1.1675966e+00},
+{1.0504944e+00},
+{9.8129158e-01},
+{7.5798016e-01},
+{7.1660079e-01},
+{8.3950658e-01},
+{1.0870027e+00},
+{1.2170776e+00},
+{1.3123779e+00},
+{1.1361782e+00},
+{7.9337369e-01},
+{5.2230472e-01},
+{4.3857925e-01},
+{8.0873950e-01},
+{9.7422631e-01},
+{9.3291515e-01},
+{1.0947530e+00},
+{1.1335086e+00},
+{1.1645714e+00},
+{1.0315895e+00},
+{7.9058261e-01},
+{6.3878936e-01},
+{6.4385427e-01},
+{9.7290237e-01},
+{1.1330941e+00},
+{1.1738960e+00},
+{1.2210669e+00},
+{9.4813374e-01},
+{7.1548595e-01},
+{5.2046031e-01},
+{6.8100333e-01},
+{1.0072944e+00},
+{1.0641199e+00},
+{1.1194312e+00},
+{1.1522817e+00},
+{9.7118023e-01},
+{8.2966445e-01},
+{6.3876024e-01},
+{7.6770138e-01},
+{1.0325752e+00},
+{1.1660632e+00},
+{1.2543878e+00},
+{1.1956003e+00},
+{8.7571542e-01},
+{6.1252082e-01},
+{4.5699619e-01},
+{7.4030148e-01},
+{1.0017485e+00},
+{9.8958385e-01},
+{1.0949833e+00},
+{1.1249612e+00},
+{1.0658962e+00},
+{9.5636335e-01},
+{7.4498806e-01},
+{7.2563393e-01},
+{8.3530455e-01},
+{1.0977307e+00},
+{1.2314926e+00},
+{1.3167422e+00},
+{1.1172604e+00},
+{7.6900341e-01},
+{5.0549771e-01},
+{4.4450990e-01},
+{8.2808038e-01},
+{9.6930396e-01},
+{9.2772189e-01},
+{1.1010458e+00},
+{1.1366939e+00},
+{1.1770457e+00},
+{1.0282839e+00},
+{7.8657093e-01},
+{6.2340354e-01},
+{6.3476140e-01},
+{9.6941037e-01},
+{1.1224823e+00},
+{1.1576217e+00},
+{1.2147442e+00},
+{9.5631199e-01},
+{7.3947874e-01},
+{5.4187646e-01},
+{6.8681641e-01},
+{1.0131445e+00},
+{1.0865854e+00},
+{1.1414849e+00},
+{1.1594630e+00},
+{9.4411600e-01},
+{7.7794034e-01},
+{5.9741518e-01},
+{7.7225037e-01},
+{1.0587360e+00},
+{1.1485933e+00},
+{1.2344562e+00},
+{1.1458853e+00},
+{8.5415118e-01},
+{6.2127481e-01},
+{4.9756097e-01},
+{8.0931406e-01},
+{1.0430891e+00},
+{1.0367506e+00},
+{1.1608048e+00},
+{1.0902522e+00},
+{9.6945804e-01},
+{7.9607346e-01},
+{6.7035674e-01},
+{8.2493000e-01},
+{1.0685565e+00},
+{1.1912458e+00},
+{1.2916937e+00},
+{1.1585237e+00},
+{8.2653804e-01},
+{5.5624667e-01},
+{4.4364773e-01},
+{7.8679896e-01},
+{9.8947432e-01},
+{9.5587476e-01},
+{1.0976735e+00},
+{1.1247419e+00},
+{1.1220470e+00},
+{9.9754667e-01},
+{7.7406653e-01},
+{6.7630712e-01},
+{7.2445263e-01},
+{1.0303591e+00},
+{1.1801427e+00},
+{1.2506686e+00},
+{1.1989987e+00},
+{8.7114663e-01},
+{6.0602798e-01},
+{4.5163741e-01},
+{7.3553573e-01},
+{9.9456302e-01},
+{9.8098646e-01},
+{1.0857031e+00},
+{1.1289641e+00},
+{1.0828069e+00},
+{9.8224963e-01},
+{7.5966277e-01},
+{7.1111527e-01},
+{7.8645769e-01},
+{1.0673541e+00},
+{1.2116816e+00},
+{1.2990734e+00},
+{1.1657704e+00},
+{8.1779454e-01},
+{5.4428063e-01},
+{4.3047549e-01},
+{7.7832590e-01},
+{9.7551443e-01},
+{9.3705618e-01},
+{1.0807206e+00},
+{1.1339189e+00},
+{1.1551319e+00},
+{1.0473610e+00},
+{8.0021464e-01},
+{6.5377513e-01},
+{6.3810292e-01},
+{9.6140773e-01},
+{1.1354401e+00},
+{1.1782311e+00},
+{1.2323246e+00},
+{9.5811452e-01},
+{7.1400985e-01},
+{5.1434848e-01},
+{6.5876782e-01},
+{9.9374878e-01},
+{1.0532057e+00},
+{1.0987291e+00},
+{1.1569941e+00},
+{9.9327584e-01},
+{8.7055783e-01},
+{6.6607204e-01},
+{7.5154249e-01},
+{9.9147904e-01},
+{1.1618652e+00},
+{1.2531013e+00},
+{1.2445235e+00},
+{9.2459418e-01},
+{6.3924685e-01},
+{4.4899067e-01},
+{6.5946924e-01},
+{9.7165260e-01},
+{9.7791817e-01},
+{1.0391898e+00},
+{1.1412631e+00},
+{1.0983393e+00},
+{1.0493420e+00},
+{8.0399406e-01},
+{7.0992449e-01},
+{7.0350356e-01},
+{9.8952236e-01},
+{1.1734521e+00},
+{1.2538876e+00},
+{1.2508500e+00},
+{9.2423636e-01},
+{6.3070030e-01},
+{4.4136962e-01},
+{6.4946966e-01},
+{9.6197955e-01},
+{9.6606332e-01},
+{1.0237953e+00},
+{1.1421522e+00},
+{1.1183774e+00},
+{1.0857179e+00},
+{8.3157725e-01},
+{7.0250588e-01},
+{6.4917325e-01},
+{9.2959329e-01},
+{1.1407976e+00},
+{1.2080261e+00},
+{1.2684960e+00},
+{9.9122930e-01},
+{7.0220017e-01},
+{4.8816416e-01},
+{5.8586111e-01},
+{9.4668329e-01},
+{1.0087590e+00},
+{1.0232927e+00},
+{1.1559444e+00},
+{1.0720927e+00},
+{1.0286336e+00},
+{7.9460252e-01},
+{7.2093651e-01},
+{7.6292167e-01},
+{1.0248985e+00},
+{1.1929944e+00},
+{1.2920208e+00},
+{1.2293181e+00},
+{8.8290244e-01},
+{5.8527613e-01},
+{4.1855360e-01},
+{6.9074767e-01},
+{9.5977708e-01},
+{9.3601019e-01},
+{1.0268467e+00},
+{1.1397909e+00},
+{1.1581327e+00},
+{1.1205956e+00},
+{8.5280669e-01},
+{6.7763483e-01},
+{5.7983286e-01},
+{8.6429914e-01},
+{1.0976939e+00},
+{1.1367408e+00},
+{1.2374931e+00},
+{1.0493382e+00},
+{8.0588138e-01},
+{5.9127581e-01},
+{5.7929225e-01},
+{9.2472931e-01},
+{1.0849831e+00},
+{1.0943246e+00},
+{1.2041235e+00},
+{1.0091917e+00},
+{8.4987188e-01},
+{6.3876182e-01},
+{6.7747918e-01},
+{9.7202288e-01},
+{1.1405471e+00},
+{1.1943368e+00},
+{1.2338428e+00},
+{9.4462558e-01},
+{6.9738430e-01},
+{4.9856007e-01},
+{6.6823589e-01},
+{9.9611375e-01},
+{1.0393748e+00},
+{1.0920087e+00},
+{1.1489492e+00},
+{1.0066576e+00},
+{8.9589007e-01},
+{6.8845995e-01},
+{7.5294149e-01},
+{9.6184563e-01},
+{1.1555071e+00},
+{1.2567316e+00},
+{1.2751778e+00},
+{9.6335246e-01},
+{6.5830948e-01},
+{4.4799275e-01},
+{5.9888825e-01},
+{9.4430988e-01},
+{9.6837958e-01},
+{9.9677549e-01},
+{1.1434629e+00},
+{1.1210684e+00},
+{1.1148356e+00},
+{8.6401556e-01},
+{7.1420118e-01},
+{6.2999725e-01},
+{8.7537864e-01},
+{1.1167941e+00},
+{1.1896694e+00},
+{1.2722030e+00},
+{1.0454715e+00},
+{7.4997564e-01},
+{5.2383173e-01},
+{5.3664145e-01},
+{9.1117041e-01},
+{1.0244044e+00},
+{1.0151287e+00},
+{1.1633675e+00},
+{1.0695966e+00},
+{1.0183575e+00},
+{8.0087884e-01},
+{7.1535296e-01},
+{7.8553095e-01},
+{1.0319822e+00},
+{1.1937155e+00},
+{1.2977947e+00},
+{1.2217806e+00},
+{8.7524512e-01},
+{5.7851885e-01},
+{4.1763620e-01},
+{7.0155638e-01},
+{9.6135267e-01},
+{9.3393602e-01},
+{1.0323424e+00},
+{1.1394608e+00},
+{1.1605598e+00},
+{1.1161968e+00},
+{8.4854339e-01},
+{6.7338626e-01},
+{5.7982826e-01},
+{8.7043086e-01},
+{1.0990834e+00},
+{1.1357404e+00},
+{1.2369383e+00},
+{1.0441753e+00},
+{8.0417958e-01},
+{5.9002711e-01},
+{5.8533894e-01},
+{9.3051649e-01},
+{1.0871279e+00},
+{1.0984983e+00},
+{1.2044155e+00},
+{1.0039892e+00},
+{8.4210523e-01},
+{6.3124655e-01},
+{6.8055115e-01},
+{9.7935183e-01},
+{1.1399170e+00},
+{1.1935307e+00},
+{1.2269029e+00},
+{9.3758049e-01},
+{6.9527243e-01},
+{5.0033084e-01},
+{6.8171448e-01},
+{1.0034848e+00},
+{1.0435853e+00},
+{1.1027381e+00},
+{1.1454200e+00},
+{9.9636446e-01},
+{8.7575610e-01},
+{6.7572455e-01},
+{7.6161436e-01},
+{9.8751885e-01},
+{1.1634852e+00},
+{1.2613366e+00},
+{1.2527158e+00},
+{9.3041078e-01},
+{6.3648886e-01},
+{4.4289908e-01},
+{6.4543043e-01},
+{9.6271252e-01},
+{9.6856037e-01},
+{1.0237816e+00},
+{1.1419384e+00},
+{1.1143808e+00},
+{1.0817980e+00},
+{8.2952128e-01},
+{7.0565231e-01},
+{6.5745758e-01},
+{9.3688510e-01},
+{1.1457239e+00},
+{1.2160319e+00},
+{1.2696485e+00},
+{9.8373294e-01},
+{6.9141844e-01},
+{4.7910268e-01},
+{5.8995166e-01},
+{9.4754885e-01},
+{1.0004197e+00},
+{1.0182334e+00},
+{1.1527974e+00},
+{1.0815601e+00},
+{1.0462772e+00},
+{8.0856012e-01},
+{7.2009150e-01},
+{7.3360533e-01},
+{9.9726771e-01},
+{1.1799228e+00},
+{1.2752553e+00},
+{1.2545993e+00},
+{9.1834232e-01},
+{6.1478702e-01},
+{4.2718988e-01},
+{6.4709630e-01},
+{9.5321724e-01},
+{9.4745071e-01},
+{1.0082615e+00},
+{1.1408283e+00},
+{1.1449070e+00},
+{1.1287695e+00},
+{8.6506953e-01},
+{6.9506068e-01},
+{5.9077914e-01},
+{8.5235412e-01},
+{1.0981812e+00},
+{1.1502068e+00},
+{1.2457878e+00},
+{1.0606248e+00},
+{7.9743949e-01},
+{5.7871635e-01},
+{5.5597309e-01},
+{9.0976389e-01},
+{1.0678545e+00},
+{1.0678466e+00},
+{1.1926843e+00},
+{1.0306506e+00},
+{9.0068600e-01},
+{6.8968565e-01},
+{6.8293693e-01},
+{9.2938386e-01},
+{1.1389931e+00},
+{1.2107723e+00},
+{1.2742112e+00},
+{9.9571305e-01},
+{7.0900966e-01},
+{4.8711002e-01},
+{5.7843327e-01},
+{9.4262722e-01},
+{1.0068885e+00},
+{1.0174671e+00},
+{1.1549847e+00},
+{1.0752383e+00},
+{1.0382561e+00},
+{8.0493588e-01},
+{7.2297438e-01},
+{7.5109199e-01},
+{1.0099650e+00},
+{1.1869526e+00},
+{1.2859723e+00},
+{1.2455314e+00},
+{9.0247113e-01},
+{5.9968946e-01},
+{4.2056794e-01},
+{6.6467784e-01},
+{9.5461231e-01},
+{9.3926954e-01},
+{1.0128964e+00},
+{1.1403075e+00},
+{1.1549599e+00},
+{1.1335031e+00},
+{8.6584651e-01},
+{6.8689154e-01},
+{5.7663890e-01},
+{8.4338430e-01},
+{1.0904343e+00},
+{1.1347127e+00},
+{1.2344704e+00},
+{1.0665197e+00},
+{8.1831436e-01},
+{6.0374950e-01},
+{5.6609914e-01},
+{9.0609488e-01},
+{1.0837698e+00},
+{1.0903349e+00},
+{1.2068005e+00},
+{1.0215332e+00},
+{8.5834739e-01},
+{6.4797779e-01},
+{6.6278967e-01},
+{9.5567807e-01},
+{1.1370612e+00},
+{1.1868501e+00},
+{1.2426235e+00},
+{9.6133342e-01},
+{7.1189926e-01},
+{5.0582127e-01},
+{6.4642134e-01},
+{9.8585814e-01},
+{1.0428580e+00},
+{1.0831242e+00},
+{1.1568123e+00},
+{1.0097872e+00},
+{9.0412446e-01},
+{6.9144384e-01},
+{7.4452934e-01},
+{9.5158341e-01},
+{1.1512270e+00},
+{1.2509608e+00},
+{1.2807229e+00},
+{9.7601316e-01},
+{6.6959369e-01},
+{4.5362019e-01},
+{5.8397806e-01},
+{9.3866865e-01},
+{9.7211974e-01},
+{9.9154526e-01},
+{1.1440232e+00},
+{1.1182310e+00},
+{1.1159711e+00},
+{8.6902975e-01},
+{7.1839537e-01},
+{6.3437176e-01},
+{8.7058758e-01},
+{1.1155207e+00},
+{1.1929730e+00},
+{1.2750340e+00},
+{1.0511137e+00},
+{7.5075715e-01},
+{5.2249794e-01},
+{5.2857771e-01},
+{9.0479637e-01},
+{1.0201490e+00},
+{1.0078239e+00},
+{1.1602784e+00},
+{1.0762699e+00},
+{1.0328279e+00},
+{8.1754050e-01},
+{7.1739458e-01},
+{7.6521302e-01},
+{1.0063562e+00},
+{1.1829441e+00},
+{1.2880301e+00},
+{1.2505618e+00},
+{9.0963666e-01},
+{6.0373594e-01},
+{4.2059572e-01},
+{6.5552332e-01},
+{9.5216646e-01},
+{9.3915492e-01},
+{1.0073402e+00},
+{1.1402595e+00},
+{1.1555473e+00},
+{1.1400569e+00},
+{8.7240707e-01},
+{6.8972093e-01},
+{5.7304964e-01},
+{8.3155186e-01},
+{1.0852244e+00},
+{1.1309096e+00},
+{1.2300408e+00},
+{1.0756716e+00},
+{8.2836037e-01},
+{6.1503305e-01},
+{5.6289537e-01},
+{8.9596963e-01},
+{1.0857176e+00},
+{1.0933045e+00},
+{1.2103223e+00},
+{1.0266092e+00},
+{8.5466111e-01},
+{6.4485312e-01},
+{6.5137619e-01},
+{9.5039035e-01},
+{1.1326982e+00},
+{1.1771304e+00},
+{1.2406618e+00},
+{9.6686921e-01},
+{7.2402007e-01},
+{5.1657512e-01},
+{6.4610863e-01},
+{9.8716024e-01},
+{1.0536774e+00},
+{1.0920775e+00},
+{1.1611436e+00},
+{9.9694608e-01},
+{8.7913715e-01},
+{6.7096137e-01},
+{7.4646346e-01},
+{9.8211586e-01},
+{1.1596887e+00},
+{1.2506463e+00},
+{1.2528610e+00},
+{9.3574881e-01},
+{6.4708026e-01},
+{4.5058777e-01},
+{6.4326949e-01},
+{9.6585146e-01},
+{9.7825812e-01},
+{1.0299115e+00},
+{1.1430802e+00},
+{1.1005190e+00},
+{1.0609387e+00},
+{8.1379890e-01},
+{7.1122428e-01},
+{6.9156533e-01},
+{9.7259709e-01},
+{1.1655186e+00},
+{1.2452699e+00},
+{1.2619116e+00},
+{9.4482161e-01},
+{6.4801701e-01},
+{4.4907240e-01},
+{6.2485209e-01},
+{9.5564190e-01},
+{9.7288683e-01},
+{1.0147847e+00},
+{1.1443809e+00},
+{1.1120870e+00},
+{1.0877802e+00},
+{8.3639407e-01},
+{7.0935594e-01},
+{6.5684224e-01},
+{9.2695542e-01},
+{1.1418485e+00},
+{1.2155793e+00},
+{1.2744439e+00},
+{9.9526406e-01},
+{6.9858658e-01},
+{4.8225678e-01},
+{5.7551868e-01},
+{9.3953863e-01},
+{1.0000682e+00},
+{1.0105854e+00},
+{1.1531271e+00},
+{1.0852683e+00},
+{1.0562598e+00},
+{8.2024340e-01},
+{7.2070006e-01},
+{7.2200828e-01},
+{9.7907123e-01},
+{1.1713283e+00},
+{1.2668075e+00},
+{1.2685662e+00},
+{9.4120299e-01},
+{6.3302397e-01},
+{4.3403723e-01},
+{6.1877701e-01},
+{9.4622798e-01},
+{9.5365292e-01},
+{9.9618857e-01},
+{1.1414351e+00},
+{1.1389950e+00},
+{1.1349258e+00},
+{8.7553815e-01},
+{7.0489527e-01},
+{5.9575516e-01},
+{8.3938416e-01},
+{1.0946321e+00},
+{1.1549299e+00},
+{1.2478627e+00},
+{1.0727433e+00},
+{8.0007945e-01},
+{5.7879852e-01},
+{5.4142544e-01},
+{8.9584895e-01},
+{1.0605852e+00},
+{1.0558398e+00},
+{1.1875826e+00},
+{1.0434789e+00},
+{9.2439267e-01},
+{7.1612758e-01},
+{6.8218882e-01},
+{9.0102182e-01},
+{1.1275375e+00},
+{1.2109971e+00},
+{1.2892493e+00},
+{1.0360675e+00},
+{7.3214326e-01},
+{4.9603224e-01},
+{5.2859768e-01},
+{9.0839931e-01},
+{9.9967438e-01},
+{9.8761933e-01},
+{1.1495807e+00},
+{1.0955451e+00},
+{1.0837190e+00},
+{8.6306190e-01},
+{7.2864571e-01},
+{6.9570443e-01},
+{9.1466309e-01},
+{1.1416079e+00},
+{1.2423455e+00},
+{1.2979661e+00},
+{1.0158501e+00},
+{6.9306586e-01},
+{4.6540187e-01},
+{5.3429520e-01},
+{9.1176535e-01},
+{9.7214664e-01},
+{9.6587930e-01},
+{1.1395672e+00},
+{1.1254350e+00},
+{1.1438751e+00},
+{9.1306791e-01},
+{7.3239337e-01},
+{6.1798523e-01},
+{7.9591503e-01},
+{1.0777494e+00},
+{1.1677842e+00},
+{1.2502967e+00},
+{1.1151699e+00},
+{8.1642087e-01},
+{5.8442000e-01},
+{5.0055038e-01},
+{8.4650946e-01},
+{1.0385843e+00},
+{1.0234916e+00},
+{1.1635033e+00},
+{1.0803258e+00},
+{9.9050756e-01},
+{8.0394987e-01},
+{6.9093478e-01},
+{8.1258118e-01},
+{1.0510811e+00},
+{1.1928214e+00},
+{1.2964341e+00},
+{1.1903709e+00},
+{8.5006682e-01},
+{5.6609363e-01},
+{4.2789827e-01},
+{7.4508986e-01},
+{9.7546850e-01},
+{9.4304490e-01},
+{1.0657257e+00},
+{1.1344752e+00},
+{1.1448680e+00},
+{1.0604924e+00},
+{8.0946851e-01},
+{6.6897242e-01},
+{6.3751840e-01},
+{9.5203759e-01},
+{1.1383222e+00},
+{1.1857882e+00},
+{1.2429358e+00},
+{9.6640521e-01},
+{7.0943525e-01},
+{5.0606242e-01},
+{6.3814517e-01},
+{9.8050653e-01},
+{1.0400252e+00},
+{1.0768445e+00},
+{1.1586073e+00},
+{1.0171349e+00},
+{9.1652446e-01},
+{7.0015343e-01},
+{7.3826470e-01},
+{9.3314098e-01},
+{1.1436325e+00},
+{1.2463125e+00},
+{1.2921798e+00},
+{1.0004180e+00},
+{6.8706555e-01},
+{4.6091370e-01},
+{5.5360860e-01},
+{9.2333217e-01},
+{9.7324082e-01},
+{9.7644851e-01},
+{1.1422917e+00},
+{1.1211038e+00},
+{1.1312591e+00},
+{8.9312684e-01},
+{7.2669146e-01},
+{6.2634170e-01},
+{8.3089176e-01},
+{1.0962164e+00},
+{1.1808500e+00},
+{1.2661262e+00},
+{1.0871224e+00},
+{7.8484345e-01},
+{5.5241172e-01},
+{5.0720010e-01},
+{8.7433135e-01},
+{1.0293171e+00},
+{1.0110677e+00},
+{1.1612664e+00},
+{1.0781429e+00},
+{1.0169296e+00},
+{8.1818733e-01},
+{7.0825239e-01},
+{7.8555548e-01},
+{1.0202406e+00},
+{1.1861871e+00},
+{1.2927766e+00},
+{1.2345608e+00},
+{8.9196638e-01},
+{5.9165129e-01},
+{4.1993302e-01},
+{6.8133251e-01},
+{9.5902336e-01},
+{9.3840491e-01},
+{1.0229760e+00},
+{1.1397483e+00},
+{1.1549910e+00},
+{1.1221729e+00},
+{8.5521466e-01},
+{6.8171599e-01},
+{5.8253142e-01},
+{8.6249156e-01},
+{1.0984374e+00},
+{1.1402897e+00},
+{1.2397438e+00},
+{1.0509675e+00},
+{8.0267914e-01},
+{5.8719202e-01},
+{5.7423177e-01},
+{9.2225657e-01},
+{1.0807070e+00},
+{1.0878295e+00},
+{1.2011335e+00},
+{1.0137713e+00},
+{8.6200406e-01},
+{6.5063788e-01},
+{6.7962388e-01},
+{9.6415425e-01},
+{1.1427244e+00},
+{1.2001432e+00},
+{1.2435862e+00},
+{9.5255718e-01},
+{6.9548843e-01},
+{4.9228114e-01},
+{6.4975070e-01},
+{9.8475452e-01},
+{1.0290189e+00},
+{1.0735305e+00},
+{1.1514964e+00},
+{1.0265685e+00},
+{9.3450570e-01},
+{7.1609613e-01},
+{7.4066401e-01},
+{9.0672547e-01},
+{1.1323663e+00},
+{1.2457251e+00},
+{1.3080265e+00},
+{1.0368462e+00},
+{7.0922252e-01},
+{4.6922499e-01},
+{5.0971665e-01},
+{8.9530783e-01},
+{9.6897032e-01},
+{9.5144881e-01},
+{1.1327578e+00},
+{1.1313397e+00},
+{1.1615669e+00},
+{9.4490349e-01},
+{7.4435097e-01},
+{6.0879030e-01},
+{7.4201167e-01},
+{1.0475442e+00},
+{1.1489683e+00},
+{1.2189341e+00},
+{1.1527726e+00},
+{8.6373864e-01},
+{6.3765290e-01},
+{5.0482479e-01},
+{7.9976041e-01},
+{1.0463811e+00},
+{1.0486243e+00},
+{1.1650654e+00},
+{1.0937932e+00},
+{9.5242412e-01},
+{7.7776887e-01},
+{6.5337298e-01},
+{8.3412675e-01},
+{1.0842165e+00},
+{1.1876958e+00},
+{1.2860798e+00},
+{1.1277640e+00},
+{8.0705117e-01},
+{5.4933954e-01},
+{4.6409423e-01},
+{8.2407983e-01},
+{1.0029510e+00},
+{9.7182671e-01},
+{1.1248927e+00},
+{1.1108497e+00},
+{1.0927585e+00},
+{9.3345740e-01},
+{7.4563087e-01},
+{6.9815644e-01},
+{8.2911579e-01},
+{1.0975320e+00},
+{1.2225208e+00},
+{1.3041931e+00},
+{1.1107874e+00},
+{7.6954799e-01},
+{5.1381033e-01},
+{4.5656108e-01},
+{8.3803614e-01},
+{9.8059578e-01},
+{9.4343837e-01},
+{1.1139527e+00},
+{1.1272959e+00},
+{1.1505047e+00},
+{9.8802150e-01},
+{7.6846480e-01},
+{6.4059710e-01},
+{7.0404249e-01},
+{1.0213995e+00},
+{1.1571646e+00},
+{1.2167098e+00},
+{1.1922700e+00},
+{8.8891917e-01},
+{6.4610240e-01},
+{4.8423413e-01},
+{7.4237703e-01},
+{1.0194305e+00},
+{1.0263817e+00},
+{1.1223002e+00},
+{1.1218476e+00},
+{1.0047937e+00},
+{8.6916869e-01},
+{6.8761628e-01},
+{7.7272726e-01},
+{9.8680374e-01},
+{1.1662112e+00},
+{1.2718586e+00},
+{1.2599891e+00},
+{9.3374084e-01},
+{6.3070745e-01},
+{4.3512068e-01},
+{6.3400337e-01},
+{9.5387123e-01},
+{9.5725486e-01},
+{1.0083783e+00},
+{1.1414776e+00},
+{1.1320033e+00},
+{1.1156485e+00},
+{8.5730304e-01},
+{7.0257566e-01},
+{6.1385070e-01},
+{8.7645096e-01},
+{1.1135407e+00},
+{1.1743915e+00},
+{1.2617479e+00},
+{1.0416530e+00},
+{7.6141001e-01},
+{5.3947941e-01},
+{5.5263397e-01},
+{9.2079176e-01},
+{1.0423877e+00},
+{1.0391593e+00},
+{1.1741828e+00},
+{1.0475738e+00},
+{9.6528247e-01},
+{7.4824631e-01},
+{7.0765109e-01},
+{8.6076413e-01},
+{1.1015853e+00},
+{1.2180296e+00},
+{1.3087379e+00},
+{1.1050105e+00},
+{7.7144492e-01},
+{5.1073157e-01},
+{4.5959721e-01},
+{8.4138746e-01},
+{9.8058403e-01},
+{9.4385625e-01},
+{1.1155190e+00},
+{1.1265194e+00},
+{1.1505430e+00},
+{9.8480260e-01},
+{7.6753361e-01},
+{6.3998096e-01},
+{7.0790430e-01},
+{1.0242649e+00},
+{1.1582776e+00},
+{1.2187970e+00},
+{1.1895283e+00},
+{8.8519343e-01},
+{6.4254017e-01},
+{4.8336487e-01},
+{7.4700679e-01},
+{1.0202300e+00},
+{1.0250636e+00},
+{1.1237335e+00},
+{1.1201468e+00},
+{1.0057497e+00},
+{8.6867488e-01},
+{6.8876595e-01},
+{7.7314271e-01},
+{9.8646241e-01},
+{1.1663720e+00},
+{1.2725046e+00},
+{1.2607985e+00},
+{9.3432428e-01},
+{6.3055002e-01},
+{4.3462242e-01},
+{6.3267663e-01},
+{9.5306639e-01},
+{9.5647018e-01},
+{1.0069834e+00},
+{1.1414283e+00},
+{1.1332454e+00},
+{1.1183329e+00},
+{8.5964718e-01},
+{7.0259273e-01},
+{6.1086847e-01},
+{8.7145976e-01},
+{1.1109278e+00},
+{1.1713319e+00},
+{1.2600859e+00},
+{1.0459933e+00},
+{7.6697548e-01},
+{5.4492361e-01},
+{5.5082792e-01},
+{9.1787603e-01},
+{1.0454451e+00},
+{1.0416026e+00},
+{1.1762039e+00},
+{1.0460129e+00},
+{9.5856257e-01},
+{7.4291843e-01},
+{7.0478730e-01},
+{8.6904294e-01},
+{1.1074327e+00},
+{1.2185136e+00},
+{1.3067057e+00},
+{1.0916662e+00},
+{7.6226341e-01},
+{5.0599582e-01},
+{4.7004755e-01},
+{8.5459323e-01},
+{9.8292600e-01},
+{9.4923741e-01},
+{1.1230180e+00},
+{1.1230727e+00},
+{1.1436380e+00},
+{9.6517685e-01},
+{7.5906667e-01},
+{6.4229098e-01},
+{7.3739829e-01},
+{1.0441989e+00},
+{1.1689429e+00},
+{1.2377221e+00},
+{1.1702644e+00},
+{8.5776744e-01},
+{6.1283507e-01},
+{4.7508171e-01},
+{7.7650778e-01},
+{1.0199875e+00},
+{1.0098181e+00},
+{1.1277738e+00},
+{1.1115547e+00},
+{1.0256012e+00},
+{8.8156161e-01},
+{7.0600708e-01},
+{7.6171841e-01},
+{9.5613909e-01},
+{1.1569502e+00},
+{1.2691300e+00},
+{1.2887802e+00},
+{9.7384680e-01},
+{6.5493328e-01},
+{4.3953117e-01},
+{5.7648851e-01},
+{9.2999054e-01},
+{9.5436230e-01},
+{9.7297008e-01},
+{1.1391325e+00},
+{1.1416064e+00},
+{1.1590944e+00},
+{9.0850247e-01},
+{7.1895834e-01},
+{5.8564424e-01},
+{7.8301903e-01},
+{1.0675300e+00},
+{1.1390766e+00},
+{1.2237314e+00},
+{1.1158432e+00},
+{8.4615038e-01},
+{6.2929929e-01},
+{5.3024321e-01},
+{8.4771779e-01},
+{1.0679772e+00},
+{1.0707805e+00},
+{1.1942615e+00},
+{1.0628072e+00},
+{9.0277875e-01},
+{7.0464579e-01},
+{6.4124982e-01},
+{8.9445063e-01},
+{1.1236998e+00},
+{1.1838208e+00},
+{1.2721938e+00},
+{1.0302053e+00},
+{7.4928918e-01},
+{5.2054789e-01},
+{5.5300914e-01},
+{9.2450978e-01},
+{1.0290172e+00},
+{1.0254177e+00},
+{1.1658431e+00},
+{1.0585030e+00},
+{9.9937151e-01},
+{7.7845423e-01},
+{7.1727834e-01},
+{8.1473462e-01},
+{1.0635825e+00},
+{1.2081434e+00},
+{1.3087387e+00},
+{1.1774543e+00},
+{8.2930325e-01},
+{5.4568406e-01},
+{4.2252006e-01},
+{7.6155262e-01},
+{9.6902023e-01},
+{9.2946430e-01},
+{1.0663917e+00},
+{1.1373062e+00},
+{1.1667915e+00},
+{1.0769457e+00},
+{8.1823128e-01},
+{6.5190054e-01},
+{6.0082155e-01},
+{9.2122516e-01},
+{1.1147361e+00},
+{1.1467530e+00},
+{1.2352757e+00},
+{9.9993521e-01},
+{7.6890308e-01},
+{5.5857496e-01},
+{6.2725763e-01},
+{9.7318317e-01},
+{1.0840117e+00},
+{1.1108847e+00},
+{1.1857549e+00},
+{9.7757101e-01},
+{8.2394503e-01},
+{6.1941336e-01},
+{7.2410931e-01},
+{1.0158088e+00},
+{1.1491174e+00},
+{1.2188178e+00},
+{1.2007209e+00},
+{8.9859946e-01},
+{6.5456633e-01},
+{4.8391373e-01},
+{7.3135136e-01},
+{1.0176181e+00},
+{1.0277501e+00},
+{1.1176213e+00},
+{1.1248859e+00},
+{1.0041498e+00},
+{8.7364691e-01},
+{6.8812425e-01},
+{7.7228478e-01},
+{9.8423833e-01},
+{1.1655135e+00},
+{1.2710944e+00},
+{1.2619166e+00},
+{9.3651452e-01},
+{6.3284215e-01},
+{4.3578889e-01},
+{6.3021849e-01},
+{9.5269846e-01},
+{9.5770175e-01},
+{1.0064613e+00},
+{1.1416014e+00},
+{1.1318041e+00},
+{1.1173687e+00},
+{8.5933718e-01},
+{7.0364317e-01},
+{6.1326177e-01},
+{8.7318554e-01},
+{1.1121947e+00},
+{1.1737687e+00},
+{1.2616019e+00},
+{1.0447114e+00},
+{7.6386287e-01},
+{5.4149208e-01},
+{5.5006680e-01},
+{9.1816862e-01},
+{1.0427545e+00},
+{1.0385725e+00},
+{1.1744959e+00},
+{1.0484442e+00},
+{9.6566520e-01},
+{7.4941645e-01},
+{7.0654030e-01},
+{8.5978495e-01},
+{1.1007328e+00},
+{1.2172148e+00},
+{1.3084224e+00},
+{1.1066295e+00},
+{7.7306455e-01},
+{5.1195750e-01},
+{4.5881820e-01},
+{8.3991753e-01},
+{9.8090418e-01},
+{9.4402667e-01},
+{1.1150495e+00},
+{1.1263864e+00},
+{1.1498512e+00},
+{9.8537193e-01},
+{7.6788821e-01},
+{6.4101222e-01},
+{7.0798171e-01},
+{1.0241973e+00},
+{1.1588402e+00},
+{1.2194902e+00},
+{1.1900225e+00},
+{8.8503290e-01},
+{6.4170616e-01},
+{4.8247262e-01},
+{7.4633801e-01},
+{1.0194608e+00},
+{1.0238758e+00},
+{1.1225142e+00},
+{1.1204876e+00},
+{1.0078894e+00},
+{8.7195748e-01},
+{6.9071922e-01},
+{7.7128559e-01},
+{9.8171063e-01},
+{1.1648359e+00},
+{1.2716060e+00},
+{1.2653194e+00},
+{9.4044785e-01},
+{6.3462126e-01},
+{4.3541986e-01},
+{6.2397592e-01},
+{9.4996429e-01},
+{9.5654324e-01},
+{1.0018949e+00},
+{1.1415375e+00},
+{1.1340702e+00},
+{1.1242483e+00},
+{8.6601272e-01},
+{7.0479002e-01},
+{6.0700568e-01},
+{8.6003770e-01},
+{1.1056434e+00},
+{1.1671804e+00},
+{1.2575999e+00},
+{1.0561104e+00},
+{7.7723774e-01},
+{5.5451638e-01},
+{5.4470017e-01},
+{9.0953268e-01},
+{1.0489983e+00},
+{1.0432715e+00},
+{1.1787522e+00},
+{1.0466535e+00},
+{9.5253913e-01},
+{7.3976965e-01},
+{6.9910727e-01},
+{8.7457184e-01},
+{1.1111747e+00},
+{1.2168058e+00},
+{1.3037145e+00},
+{1.0820947e+00},
+{7.5710433e-01},
+{5.0441461e-01},
+{4.7923251e-01},
+{8.6434525e-01},
+{9.8624111e-01},
+{9.5555561e-01},
+{1.1291297e+00},
+{1.1187232e+00},
+{1.1339455e+00},
+{9.4624297e-01},
+{7.5185473e-01},
+{6.4886735e-01},
+{7.6947931e-01},
+{1.0640658e+00},
+{1.1819490e+00},
+{1.2581006e+00},
+{1.1479357e+00},
+{8.2795383e-01},
+{5.8084914e-01},
+{4.6968322e-01},
+{8.0540679e-01},
+{1.0147037e+00},
+{9.9267552e-01},
+{1.1297166e+00},
+{1.1074520e+00},
+{1.0535732e+00},
+{8.9989357e-01},
+{7.2414622e-01},
+{7.3710872e-01},
+{9.0842211e-01},
+{1.1372436e+00},
+{1.2550645e+00},
+{1.3118017e+00},
+{1.0309191e+00},
+{6.9715233e-01},
+{4.6014528e-01},
+{5.1093338e-01},
+{8.9602085e-01},
+{9.6063866e-01},
+{9.4454964e-01},
+{1.1299822e+00},
+{1.1400660e+00},
+{1.1784050e+00},
+{9.5942169e-01},
+{7.4592605e-01},
+{5.9179210e-01},
+{7.0833096e-01},
+{1.0269127e+00},
+{1.1280089e+00},
+{1.1874924e+00},
+{1.1668412e+00},
+{8.9924653e-01},
+{6.8916581e-01},
+{5.3047422e-01},
+{7.7534076e-01},
+{1.0549099e+00},
+{1.0847312e+00},
+{1.1818109e+00},
+{1.1071479e+00},
+{9.0609669e-01},
+{7.2016981e-01},
+{5.9922569e-01},
+{8.4631545e-01},
+{1.1007330e+00},
+{1.1539455e+00},
+{1.2548057e+00},
+{1.0707369e+00},
+{7.9955359e-01},
+{5.7211183e-01},
+{5.3729384e-01},
+{8.9511329e-01},
+{1.0559775e+00},
+{1.0482488e+00},
+{1.1833103e+00},
+{1.0467011e+00},
+{9.3892077e-01},
+{7.3109756e-01},
+{6.8881096e-01},
+{8.8724202e-01},
+{1.1196405e+00},
+{1.2137632e+00},
+{1.2969341e+00},
+{1.0598913e+00},
+{7.4476987e-01},
+{5.0025043e-01},
+{5.0175473e-01},
+{8.8612613e-01},
+{9.9295902e-01},
+{9.7027740e-01},
+{1.1406663e+00},
+{1.1082236e+00},
+{1.1111857e+00},
+{9.0519862e-01},
+{7.3853971e-01},
+{6.6752554e-01},
+{8.4076984e-01},
+{1.1041197e+00},
+{1.2107499e+00},
+{1.2910787e+00},
+{1.0889124e+00},
+{7.6218879e-01},
+{5.1854183e-01},
+{4.8212027e-01},
+{8.6343438e-01},
+{9.9664176e-01},
+{9.6786348e-01},
+{1.1354766e+00},
+{1.1100558e+00},
+{1.1078273e+00},
+{9.1950063e-01},
+{7.4186814e-01},
+{6.7554741e-01},
+{8.2771704e-01},
+{1.0970261e+00},
+{1.2115055e+00},
+{1.2926801e+00},
+{1.1044430e+00},
+{7.7268354e-01},
+{5.2367729e-01},
+{4.6962326e-01},
+{8.4775775e-01},
+{9.9325612e-01},
+{9.6094332e-01},
+{1.1271528e+00},
+{1.1156670e+00},
+{1.1183008e+00},
+{9.4351589e-01},
+{7.5035067e-01},
+{6.6773972e-01},
+{7.8886291e-01},
+{1.0750322e+00},
+{1.1971741e+00},
+{1.2770426e+00},
+{1.1387571e+00},
+{8.0837143e-01},
+{5.5509702e-01},
+{4.5955065e-01},
+{8.1398530e-01},
+{1.0008314e+00},
+{9.7057086e-01},
+{1.1195985e+00},
+{1.1149111e+00},
+{1.0957539e+00},
+{9.4451157e-01},
+{7.4819097e-01},
+{6.9474604e-01},
+{8.1250200e-01},
+{1.0876804e+00},
+{1.2158509e+00},
+{1.2988266e+00},
+{1.1270851e+00},
+{7.8595861e-01},
+{5.2690470e-01},
+{4.5032342e-01},
+{8.2266007e-01},
+{9.8371303e-01},
+{9.4630598e-01},
+{1.1090276e+00}};
+
+    private static readonly Dataset defaultDataset;
+    private static readonly IEnumerable<string> defaultAllowedInputVariables;
+    private static readonly string defaultTargetVariable;
+
+    static TimeSeriesPrognosisProblemData() {
+      defaultDataset = new Dataset(new string[] { "x" }, mackey_glass_17);
+      defaultDataset.Name = "Mackey-Glass (t=17) Time Series Benchmark Dataset";
+      defaultAllowedInputVariables = Enumerable.Empty<string>();
+      defaultTargetVariable = "x";
+    }
+    #endregion
+
+    private const string TrainingHorizonParameterName = "Training Horizon";
+    private const string TestHorizonParameterName = "Test Horizon";
+
+    public IFixedValueParameter<IntValue> TrainingHorizonParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TrainingHorizonParameterName]; }
+    }
+    public IFixedValueParameter<IntValue> TestHorizonParameter {
+      get { return (IFixedValueParameter<IntValue>)Parameters[TestHorizonParameterName]; }
+    }
+
+    #region Properties
+    public int TrainingHorizon {
+      get { return TrainingHorizonParameter.Value.Value; }
+      set { TrainingHorizonParameter.Value.Value = value; }
+    }
+
+    public int TestHorizon {
+      get { return TestHorizonParameter.Value.Value; }
+      set { TestHorizonParameter.Value.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisProblemData(bool deserializing) : base(deserializing) { }
+
+    protected TimeSeriesPrognosisProblemData(TimeSeriesPrognosisProblemData original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisProblemData(this, cloner);
+    }
+
+    public TimeSeriesPrognosisProblemData()
+      : this(defaultDataset, defaultAllowedInputVariables, defaultTargetVariable) {
+      TrainingPartition.Start = 50;
+    }
+    public TimeSeriesPrognosisProblemData(Dataset dataset, IEnumerable<string> allowedInputVariables, string targetVariable)
+      : base(dataset, allowedInputVariables, targetVariable) {
+      Parameters.Add(new FixedValueParameter<IntValue>(TrainingHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each training sample.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<IntValue>(TestHorizonParameterName, "Specifies the horizon (how far the prognosis reaches in the future) for each test sample.", new IntValue(1)));
+
+      TrainingHorizonParameter.Hidden = true;
+      TestHorizonParameter.Hidden = true;
+
+      TrainingPartition.Start = Math.Min((int)(TrainingPartition.Size * 0.2), 50);
+
+      RegisterParameterEventHandlers();
+    }
+
+    public TimeSeriesPrognosisProblemData(ITimeSeriesPrognosisProblemData timeseriesProblemData)
+      : this(timeseriesProblemData.Dataset, timeseriesProblemData.AllowedInputVariables, timeseriesProblemData.TargetVariable) {
+
+      TestHorizon = timeseriesProblemData.TestHorizon;
+      TrainingHorizon = timeseriesProblemData.TestHorizon;
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEventHandlers();
+    }
+
+    private void RegisterParameterEventHandlers() {
+      TrainingHorizonParameter.Value.ValueChanged += new System.EventHandler(Parameter_ValueChanged);
+      TestHorizonParameter.Value.ValueChanged += new System.EventHandler(Parameter_ValueChanged);
+    }
+
+    private void Parameter_ValueChanged(object sender, EventArgs e) {
+      OnChanged();
+    }
+
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisResults.cs	(revision 16097)
@@ -0,0 +1,456 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  [Item("Prognosis Results", "Represents a collection of time series prognosis results.")]
+  public class TimeSeriesPrognosisResults : ResultCollection {
+    #region result names
+    protected const string PrognosisTrainingMeanSquaredErrorResultName = "Mean squared error (training)";
+    protected const string PrognosisTestMeanSquaredErrorResultName = "Mean squared error (test)";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultName = "Mean absolute error (training)";
+    protected const string PrognosisTestMeanAbsoluteErrorResultName = "Mean absolute error (test)";
+    protected const string PrognosisTrainingSquaredCorrelationResultName = "Pearson's R² (training)";
+    protected const string PrognosisTestSquaredCorrelationResultName = "Pearson's R² (test)";
+    protected const string PrognosisTrainingRelativeErrorResultName = "Average relative error (training)";
+    protected const string PrognosisTestRelativeErrorResultName = "Average relative error (test)";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (training)";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultName = "Normalized mean squared error (test)";
+    protected const string PrognosisTrainingMeanErrorResultName = "Mean error (training)";
+    protected const string PrognosisTestMeanErrorResultName = "Mean error (test)";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    protected const string PrognosisTestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (test)";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
+    protected const string PrognosisTestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
+    #endregion
+
+    #region result descriptions
+    protected const string PrognosisTrainingMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestMeanSquaredErrorResultDescription = "Mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the training partition";
+    protected const string PrognosisTestMeanAbsoluteErrorResultDescription = "Mean of absolute errors of the model on the test partition";
+    protected const string PrognosisTrainingSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the training partition";
+    protected const string PrognosisTestSquaredCorrelationResultDescription = "Squared Pearson's correlation coefficient of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the training partition";
+    protected const string PrognosisTestRelativeErrorResultDescription = "Average of the relative errors of the model output and the actual values on the test partition";
+    protected const string PrognosisTrainingNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the training partition";
+    protected const string PrognosisTestNormalizedMeanSquaredErrorResultDescription = "Normalized mean of squared errors of the model on the test partition";
+    protected const string PrognosisTrainingMeanErrorResultDescription = "Mean of errors of the model on the training partition";
+    protected const string PrognosisTestMeanErrorResultDescription = "Mean of errors of the model on the test partition";
+
+    protected const string PrognosisTrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
+    protected const string PrognosisTestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
+    protected const string PrognosisTrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
+    protected const string PrognosisTestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
+    #endregion
+
+    #region result properties
+    //prognosis results for different horizons
+    public double PrognosisTrainingMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingMeanSquaredErrorResultName, PrognosisTrainingMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanSquaredErrorResultName)) Add(new Result(PrognosisTestMeanSquaredErrorResultName, PrognosisTestMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTrainingMeanAbsoluteErrorResultName, PrognosisTrainingMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanAbsoluteError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanAbsoluteErrorResultName)) Add(new Result(PrognosisTestMeanAbsoluteErrorResultName, PrognosisTestMeanAbsoluteErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanAbsoluteErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRSquared {
+      get {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingSquaredCorrelationResultName)) Add(new Result(PrognosisTrainingSquaredCorrelationResultName, PrognosisTrainingSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRSquared {
+      get {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestSquaredCorrelationResultName)) Add(new Result(PrognosisTestSquaredCorrelationResultName, PrognosisTestSquaredCorrelationResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestSquaredCorrelationResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingRelativeErrorResultName)) Add(new Result(PrognosisTrainingRelativeErrorResultName, PrognosisTrainingRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestRelativeError {
+      get {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestRelativeErrorResultName)) Add(new Result(PrognosisTestRelativeErrorResultName, PrognosisTestRelativeErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestRelativeErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTrainingNormalizedMeanSquaredErrorResultName, PrognosisTrainingNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestNormalizedMeanSquaredError {
+      get {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestNormalizedMeanSquaredErrorResultName)) Add(new Result(PrognosisTestNormalizedMeanSquaredErrorResultName, PrognosisTestNormalizedMeanSquaredErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestNormalizedMeanSquaredErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTrainingMeanError {
+      get {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingMeanErrorResultName)) Add(new Result(PrognosisTrainingMeanErrorResultName, PrognosisTrainingMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+    public double PrognosisTestMeanError {
+      get {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestMeanErrorResultName)) Add(new Result(PrognosisTestMeanErrorResultName, PrognosisTestMeanErrorResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestMeanErrorResultName].Value).Value = value;
+      }
+    }
+
+
+    public double PrognosisTrainingDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingDirectionalSymmetryResultName, PrognosisTrainingDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestDirectionalSymmetryResultName)) Add(new Result(PrognosisTestDirectionalSymmetryResultName, PrognosisTestDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTrainingWeightedDirectionalSymmetryResultName, PrognosisTrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestWeightedDirectionalSymmetry {
+      get {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestWeightedDirectionalSymmetryResultName)) Add(new Result(PrognosisTestWeightedDirectionalSymmetryResultName, PrognosisTestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestWeightedDirectionalSymmetryResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticAR1ResultName, PrognosisTrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticAR1 {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticAR1ResultName)) Add(new Result(PrognosisTestTheilsUStatisticAR1ResultName, PrognosisTestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticAR1ResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTrainingTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTrainingTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTrainingTheilsUStatisticMeanResultName, PrognosisTrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTrainingTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    public double PrognosisTestTheilsUStatisticMean {
+      get {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) return double.NaN;
+        return ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value;
+      }
+      private set {
+        if (!ContainsKey(PrognosisTestTheilsUStatisticMeanResultName)) Add(new Result(PrognosisTestTheilsUStatisticMeanResultName, PrognosisTestTheilsUStatisticMeanResultDescription, new DoubleValue()));
+        ((DoubleValue)this[PrognosisTestTheilsUStatisticMeanResultName].Value).Value = value;
+      }
+    }
+    #endregion
+
+    [Storable]
+    private int trainingHorizon;
+    public int TrainingHorizon {
+      get { return trainingHorizon; }
+      set {
+        if (trainingHorizon != value) {
+          trainingHorizon = value;
+          OnTrainingHorizonChanged();
+        }
+      }
+    }
+
+    [Storable]
+    private int testHorizon;
+    public int TestHorizon {
+      get { return testHorizon; }
+      set {
+        if (testHorizon != value) {
+          testHorizon = value;
+          OnTestHorizonChanged();
+        }
+      }
+    }
+
+    private ITimeSeriesPrognosisSolution solution;
+    [Storable]
+    public ITimeSeriesPrognosisSolution Solution {
+      get { return solution; }
+      private set { solution = value; } //necessary for persistence
+    }
+
+    [StorableConstructor]
+    public TimeSeriesPrognosisResults(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisResults(TimeSeriesPrognosisResults original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new TimeSeriesPrognosisResults(this, cloner);
+    }
+
+    public TimeSeriesPrognosisResults(int trainingHorizon, int testHorizon, ITimeSeriesPrognosisSolution solution)
+      : base() {
+      this.trainingHorizon = trainingHorizon;
+      this.testHorizon = testHorizon;
+      this.solution = solution;
+      CalculateTrainingPrognosisResults();
+      CalculateTestPrognosisResults();
+    }
+
+    #region events
+    public event EventHandler TrainingHorizonChanged;
+    protected virtual void OnTrainingHorizonChanged() {
+      CalculateTrainingPrognosisResults();
+      var handler = TrainingHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+
+    public event EventHandler TestHorizonChanged;
+    protected virtual void OnTestHorizonChanged() {
+      CalculateTestPrognosisResults();
+      var handler = TestHorizonChanged;
+      if (handler != null) handler(this, EventArgs.Empty);
+    }
+    #endregion
+
+    private void CalculateTrainingPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      var trainingHorizions = problemData.TrainingIndices.Select(r => Math.Min(trainingHorizon, problemData.TrainingPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingTargetValues = problemData.TrainingIndices.Zip(trainingHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> trainingEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+      IEnumerable<IEnumerable<double>> trainingAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TrainingIndices, trainingHorizions).ToList();
+
+      IEnumerable<double> originalTrainingValues = trainingTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTrainingValues = trainingEstimatedValues.SelectMany(x => x).ToList();
+
+      double trainingMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingMSE : double.NaN;
+      double trainingMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanAbsoluteError = errorState == OnlineCalculatorError.None ? trainingMAE : double.NaN;
+      double trainingR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRSquared = errorState == OnlineCalculatorError.None ? trainingR2 : double.NaN;
+      double trainingRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingRelativeError = errorState == OnlineCalculatorError.None ? trainingRelError : double.NaN;
+      double trainingNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? trainingNMSE : double.NaN;
+      double trainingME = OnlineMeanErrorCalculator.Calculate(originalTrainingValues, estimatedTrainingValues, out errorState);
+      PrognosisTrainingMeanError = errorState == OnlineCalculatorError.None ? trainingME : double.NaN;
+
+      PrognosisTrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingDirectionalSymmetry : 0.0;
+      PrognosisTrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingEstimatedValues, out errorState);
+      PrognosisTrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTrainingWeightedDirectionalSymmetry : 0.0;
+      PrognosisTrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingStartValues, trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
+      PrognosisTrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTrainingTheilsUStatisticMean : double.PositiveInfinity;
+    }
+
+    private void CalculateTestPrognosisResults() {
+      OnlineCalculatorError errorState;
+      var problemData = Solution.ProblemData;
+      var model = Solution.Model;
+      //mean model
+      double trainingMean = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      //AR1 model
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(problemData.TargetVariable, new double[] { beta }, alpha);
+
+      var testHorizions = problemData.TestIndices.Select(r => Math.Min(testHorizon, problemData.TestPartition.End - r)).ToList();
+      IEnumerable<IEnumerable<double>> testTargetValues = problemData.TestIndices.Zip(testHorizions, Enumerable.Range).Select(r => problemData.Dataset.GetDoubleValues(problemData.TargetVariable, r)).ToList();
+      IEnumerable<IEnumerable<double>> testEstimatedValues = model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<double> testStartValues = problemData.Dataset.GetDoubleValues(problemData.TargetVariable, problemData.TestIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      IEnumerable<IEnumerable<double>> testMeanModelPredictions = meanModel.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+      IEnumerable<IEnumerable<double>> testAR1ModelPredictions = AR1model.GetPrognosedValues(problemData.Dataset, problemData.TestIndices, testHorizions).ToList();
+
+      IEnumerable<double> originalTestValues = testTargetValues.SelectMany(x => x).ToList();
+      IEnumerable<double> estimatedTestValues = testEstimatedValues.SelectMany(x => x).ToList();
+
+      double testMSE = OnlineMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanSquaredError = errorState == OnlineCalculatorError.None ? testMSE : double.NaN;
+      double testMAE = OnlineMeanAbsoluteErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanAbsoluteError = errorState == OnlineCalculatorError.None ? testMAE : double.NaN;
+      double testR2 = OnlinePearsonsRSquaredCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRSquared = errorState == OnlineCalculatorError.None ? testR2 : double.NaN;
+      double testRelError = OnlineMeanAbsolutePercentageErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestRelativeError = errorState == OnlineCalculatorError.None ? testRelError : double.NaN;
+      double testNMSE = OnlineNormalizedMeanSquaredErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestNormalizedMeanSquaredError = errorState == OnlineCalculatorError.None ? testNMSE : double.NaN;
+      double testME = OnlineMeanErrorCalculator.Calculate(originalTestValues, estimatedTestValues, out errorState);
+      PrognosisTestMeanError = errorState == OnlineCalculatorError.None ? testME : double.NaN;
+
+      PrognosisTestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestDirectionalSymmetry : 0.0;
+      PrognosisTestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testStartValues, testTargetValues, testEstimatedValues, out errorState);
+      PrognosisTestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? PrognosisTestWeightedDirectionalSymmetry : 0.0;
+      PrognosisTestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticAR1 : double.PositiveInfinity;
+      PrognosisTestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testStartValues, testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
+      PrognosisTestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? PrognosisTestTheilsUStatisticMean : double.PositiveInfinity;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolution.cs	(revision 16097)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  /// <summary>
+  /// Represents a time series prognosis data analysis solution
+  /// </summary>
+  [StorableClass]
+  public class TimeSeriesPrognosisSolution : TimeSeriesPrognosisSolutionBase {
+    [StorableConstructor]
+    protected TimeSeriesPrognosisSolution(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolution(TimeSeriesPrognosisSolution original, Cloner cloner) : base(original, cloner) { }
+    protected internal TimeSeriesPrognosisSolution(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      CalculateRegressionResults();
+      CalculateTimeSeriesResults();
+      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
+    }
+
+    public override IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizons) {
+      return Model.GetPrognosedValues(ProblemData.Dataset, rows, horizons);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Implementation/TimeSeriesPrognosis/TimeSeriesPrognosisSolutionBase.cs	(revision 16097)
@@ -0,0 +1,197 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [StorableClass]
+  public abstract class TimeSeriesPrognosisSolutionBase : RegressionSolutionBase, ITimeSeriesPrognosisSolution {
+    #region result names
+    protected const string TrainingDirectionalSymmetryResultName = "Average directional symmetry (training)";
+    protected const string TestDirectionalSymmetryResultName = "Average directional symmetry (test)";
+    protected const string TrainingWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (training)";
+    protected const string TestWeightedDirectionalSymmetryResultName = "Average weighted directional symmetry (test)";
+    protected const string TrainingTheilsUStatisticAR1ResultName = "Theil's U2 (AR1) (training)";
+    protected const string TestTheilsUStatisticLastResultName = "Theil's U2 (AR1) (test)";
+    protected const string TrainingTheilsUStatisticMeanResultName = "Theil's U2 (mean) (training)";
+    protected const string TestTheilsUStatisticMeanResultName = "Theil's U2 (mean) (test)";
+    protected const string TimeSeriesPrognosisResultName = "Prognosis Results";
+    #endregion
+
+    #region result descriptions
+    protected const string TrainingDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the training partition";
+    protected const string TestDirectionalSymmetryResultDescription = "The average directional symmetry of the forecasts of the model on the test partition";
+    protected const string TrainingWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the training partition";
+    protected const string TestWeightedDirectionalSymmetryResultDescription = "The average weighted directional symmetry of the forecasts of the model on the test partition";
+    protected const string TrainingTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the training partition";
+    protected const string TestTheilsUStatisticAR1ResultDescription = "The Theil's U statistic (reference: AR1 model) of the forecasts of the model on the test partition";
+    protected const string TrainingTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean model) of the forecasts of the model on the training partition";
+    protected const string TestTheilsUStatisticMeanResultDescription = "The Theil's U statistic (reference: mean value) of the forecasts of the model on the test partition";
+    protected const string TimeSeriesPrognosisResultDescription = "The calculated results of predictions in the future.";
+    #endregion
+
+    public new ITimeSeriesPrognosisModel Model {
+      get { return (ITimeSeriesPrognosisModel)base.Model; }
+      protected set { base.Model = value; }
+    }
+
+    public new ITimeSeriesPrognosisProblemData ProblemData {
+      get { return (ITimeSeriesPrognosisProblemData)base.ProblemData; }
+      set { base.ProblemData = value; }
+    }
+
+    public abstract IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
+
+    #region Results
+    public double TrainingDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TestWeightedDirectionalSymmetry {
+      get { return ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestWeightedDirectionalSymmetryResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticAR1 {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticAR1ResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticAR1 {
+      get { return ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticLastResultName].Value).Value = value; }
+    }
+    public double TrainingTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TrainingTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+    public double TestTheilsUStatisticMean {
+      get { return ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value; }
+      private set { ((DoubleValue)this[TestTheilsUStatisticMeanResultName].Value).Value = value; }
+    }
+
+    public TimeSeriesPrognosisResults TimeSeriesPrognosisResults {
+      get {
+        if (!ContainsKey(TimeSeriesPrognosisResultName)) return null;
+        return (TimeSeriesPrognosisResults)this[TimeSeriesPrognosisResultName];
+      }
+      set {
+        if (ContainsKey(TimeSeriesPrognosisResultName)) Remove(TimeSeriesPrognosisResultName);
+        Add(new Result(TimeSeriesPrognosisResultName, TimeSeriesPrognosisResultDescription, value));
+      }
+    }
+    #endregion
+
+
+    public override IEnumerable<double> EstimatedValues {
+      get { return GetEstimatedValues(Enumerable.Range(0, ProblemData.Dataset.Rows)); }
+    }
+    public override IEnumerable<double> EstimatedTrainingValues {
+      get { return GetEstimatedValues(ProblemData.TrainingIndices); }
+    }
+    public override IEnumerable<double> EstimatedTestValues {
+      get { return GetEstimatedValues(ProblemData.TestIndices); }
+    }
+    public override IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows) {
+      return Model.GetEstimatedValues(ProblemData.Dataset, rows);
+    }
+
+    [StorableConstructor]
+    protected TimeSeriesPrognosisSolutionBase(bool deserializing) : base(deserializing) { }
+    protected TimeSeriesPrognosisSolutionBase(TimeSeriesPrognosisSolutionBase original, Cloner cloner) : base(original, cloner) { }
+    protected TimeSeriesPrognosisSolutionBase(ITimeSeriesPrognosisModel model, ITimeSeriesPrognosisProblemData problemData)
+      : base(model, problemData) {
+      Add(new Result(TrainingDirectionalSymmetryResultName, TrainingDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TestDirectionalSymmetryResultName, TestDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TrainingWeightedDirectionalSymmetryResultName, TrainingWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TestWeightedDirectionalSymmetryResultName, TestWeightedDirectionalSymmetryResultDescription, new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticAR1ResultName, TrainingTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticLastResultName, TestTheilsUStatisticAR1ResultDescription, new DoubleValue()));
+      Add(new Result(TrainingTheilsUStatisticMeanResultName, TrainingTheilsUStatisticMeanResultDescription, new DoubleValue()));
+      Add(new Result(TestTheilsUStatisticMeanResultName, TestTheilsUStatisticMeanResultDescription, new DoubleValue()));
+    }
+
+    protected override void RecalculateResults() {
+      base.RecalculateResults();
+      CalculateTimeSeriesResults();
+      CalculateTimeSeriesResults(ProblemData.TrainingHorizon, ProblemData.TestHorizon);
+    }
+
+    protected void CalculateTimeSeriesResults() {
+      OnlineCalculatorError errorState;
+      double trainingMean = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).Average();
+      var meanModel = new ConstantTimeSeriesPrognosisModel(trainingMean);
+
+      double alpha, beta;
+      IEnumerable<double> trainingStartValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Select(r => r - 1).Where(r => r > 0)).ToList();
+      OnlineLinearScalingParameterCalculator.Calculate(ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices.Where(x => x > 0)), trainingStartValues, out alpha, out beta, out errorState);
+      var AR1model = new TimeSeriesPrognosisAutoRegressiveModel(ProblemData.TargetVariable, new double[] { beta }, alpha);
+
+
+      #region Calculate training quality measures
+      IEnumerable<double> trainingTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TrainingIndices).ToList();
+      IEnumerable<double> trainingEstimatedValues = EstimatedTrainingValues.ToList();
+      IEnumerable<double> trainingMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
+      IEnumerable<double> trainingAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TrainingIndices).ToList();
+
+      TrainingDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
+      TrainingDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingDirectionalSymmetry : 0.0;
+      TrainingWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingEstimatedValues, out errorState);
+      TrainingWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TrainingWeightedDirectionalSymmetry : 0.0;
+      TrainingTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingAR1ModelPredictions, trainingEstimatedValues, out errorState);
+      TrainingTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticAR1 : double.PositiveInfinity;
+      TrainingTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(trainingTargetValues.First(), trainingTargetValues, trainingMeanModelPredictions, trainingEstimatedValues, out errorState);
+      TrainingTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TrainingTheilsUStatisticMean : double.PositiveInfinity;
+      #endregion
+
+      #region Calculate test quality measures
+      IEnumerable<double> testTargetValues = ProblemData.Dataset.GetDoubleValues(ProblemData.TargetVariable, ProblemData.TestIndices).ToList();
+      IEnumerable<double> testEstimatedValues = EstimatedTestValues.ToList();
+      IEnumerable<double> testMeanModelPredictions = meanModel.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
+      IEnumerable<double> testAR1ModelPredictions = AR1model.GetEstimatedValues(ProblemData.Dataset, ProblemData.TestIndices).ToList();
+
+      TestDirectionalSymmetry = OnlineDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
+      TestDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestDirectionalSymmetry : 0.0;
+      TestWeightedDirectionalSymmetry = OnlineWeightedDirectionalSymmetryCalculator.Calculate(testTargetValues.First(), testTargetValues, testEstimatedValues, out errorState);
+      TestWeightedDirectionalSymmetry = errorState == OnlineCalculatorError.None ? TestWeightedDirectionalSymmetry : 0.0;
+      TestTheilsUStatisticAR1 = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testAR1ModelPredictions, testEstimatedValues, out errorState);
+      TestTheilsUStatisticAR1 = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticAR1 : double.PositiveInfinity;
+      TestTheilsUStatisticMean = OnlineTheilsUStatisticCalculator.Calculate(testTargetValues.First(), testTargetValues, testMeanModelPredictions, testEstimatedValues, out errorState);
+      TestTheilsUStatisticMean = errorState == OnlineCalculatorError.None ? TestTheilsUStatisticMean : double.PositiveInfinity;
+      #endregion
+    }
+
+    protected void CalculateTimeSeriesResults(int trainingHorizon, int testHorizon) {
+      TimeSeriesPrognosisResults = new TimeSeriesPrognosisResults(trainingHorizon, testHorizon, this);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleModel.cs	(revision 16097)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationEnsembleModel : IClassificationModel {
+    void Add(IClassificationModel model);
+    void Remove(IClassificationModel model);
+    IEnumerable<IClassificationModel> Models { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolution.cs	(revision 16097)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationEnsembleSolution : IClassificationSolution {
+    new IClassificationEnsembleModel Model { get; }
+    ICheckedItemCollection<IClassificationSolution> ClassificationSolutions { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedClassValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolutionWeightCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolutionWeightCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationEnsembleSolutionWeightCalculator.cs	(revision 16097)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public delegate bool CheckPoint(IClassificationProblemData problemData, int point);
+
+  public interface IClassificationEnsembleSolutionWeightCalculator : INamedItem {
+    void CalculateNormalizedWeights(IEnumerable<IClassificationSolution> classificationSolutions);
+    IEnumerable<double> AggregateEstimatedClassValues(IEnumerable<IClassificationSolution> solutions, Dataset dataset, IEnumerable<int> rows, CheckPoint handler);
+    double GetConfidence(IEnumerable<IClassificationSolution> solutions, int index, double estimatedClassValue, CheckPoint handler);
+    IEnumerable<double> GetConfidence(IEnumerable<IClassificationSolution> solutions, IEnumerable<int> indices, IEnumerable<double> estimatedClassValue, CheckPoint handler);
+
+    CheckPoint GetTestClassDelegate();
+    CheckPoint GetTrainingClassDelegate();
+    CheckPoint GetAllClassDelegate();
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationModel.cs	(revision 16097)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationModel : IDataAnalysisModel {
+    IEnumerable<double> GetEstimatedClassValues(Dataset dataset, IEnumerable<int> rows);
+    IClassificationSolution CreateClassificationSolution(IClassificationProblemData problemData);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblem.cs	(revision 16097)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationProblem : IDataAnalysisProblem<IClassificationProblemData> {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationProblemData.cs	(revision 16097)
@@ -0,0 +1,40 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationProblemData : IDataAnalysisProblemData {
+    string TargetVariable { get; }
+
+    IEnumerable<string> ClassNames { get; }
+    IEnumerable<double> ClassValues { get; }
+    int Classes { get; }
+
+    string GetClassName(double classValue);
+    double GetClassValue(string className);
+    void SetClassName(double classValue, string className);
+
+    double GetClassificationPenalty(string correctClass, string estimatedClass);
+    double GetClassificationPenalty(double correctClassValue, double estimatedClassValue);
+    void SetClassificationPenalty(string correctClassName, string estimatedClassName, double penalty);
+    void SetClassificationPenalty(double correctClassValue, double estimatedClassValue, double penalty);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IClassificationSolution.cs	(revision 16097)
@@ -0,0 +1,36 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClassificationSolution : IDataAnalysisSolution {
+    new IClassificationModel Model { get; }
+    new IClassificationProblemData ProblemData { get; set; }
+
+    IEnumerable<double> EstimatedClassValues { get; }
+    IEnumerable<double> EstimatedTrainingClassValues { get; }
+    IEnumerable<double> EstimatedTestClassValues { get; }
+    IEnumerable<double> GetEstimatedClassValues(IEnumerable<int> rows);
+
+    double TrainingAccuracy { get; }
+    double TestAccuracy { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationModel.cs	(revision 16097)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDiscriminantFunctionClassificationModel : IClassificationModel {
+    IEnumerable<double> Thresholds { get; }
+    IEnumerable<double> ClassValues { get; }
+    IDiscriminantFunctionThresholdCalculator ThresholdCalculator { get; }
+    void RecalculateModelParameters(IClassificationProblemData problemData, IEnumerable<int> rows);
+    // class values and thresholds can only be assigned simultanously
+    void SetThresholdsAndClassValues(IEnumerable<double> thresholds, IEnumerable<double> classValues);
+    IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows);
+
+    event EventHandler ThresholdsChanged;
+
+    IDiscriminantFunctionClassificationSolution CreateDiscriminantFunctionClassificationSolution(IClassificationProblemData problemData);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionClassificationSolution.cs	(revision 16097)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDiscriminantFunctionClassificationSolution : IClassificationSolution {
+    new IDiscriminantFunctionClassificationModel Model { get; }
+
+    IEnumerable<double> EstimatedValues { get; }
+    IEnumerable<double> EstimatedTrainingValues { get; }
+    IEnumerable<double> EstimatedTestValues { get; }
+    IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Classification/IDiscriminantFunctionThresholdCalculator.cs	(revision 16097)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDiscriminantFunctionThresholdCalculator : INamedItem {
+    void Calculate(IClassificationProblemData problemData, IEnumerable<double> estimatedValues, IEnumerable<double> targetClassValues, out double[] classValues, out double[] thresholds);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringModel.cs	(revision 16097)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClusteringModel : IDataAnalysisModel {
+    IEnumerable<int> GetClusterValues(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblem.cs	(revision 16097)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClusteringProblem : IDataAnalysisProblem<IClusteringProblemData> {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringProblemData.cs	(revision 16097)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClusteringProblemData : IDataAnalysisProblemData {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Clustering/IClusteringSolution.cs	(revision 16097)
@@ -0,0 +1,33 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IClusteringSolution : IDataAnalysisSolution {
+    new IClusteringModel Model { get; }
+    new IClusteringProblemData ProblemData { get; set; }
+
+    IEnumerable<int> ClusterValues { get; }
+    IEnumerable<int> TrainingClusterValues { get; }
+    IEnumerable<int> TestClusterValues { get; }
+    IEnumerable<int> GetClusterValues(IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisModel.cs	(revision 16097)
@@ -0,0 +1,27 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisModel : INamedItem {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblem.cs	(revision 16097)
@@ -0,0 +1,38 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisProblem : IProblem {
+    IParameter ProblemDataParameter { get; }
+    IDataAnalysisProblemData ProblemData { get; }
+    event EventHandler ProblemDataChanged;
+  }
+
+  public interface IDataAnalysisProblem<T> : IDataAnalysisProblem
+  where T : class, IDataAnalysisProblemData {
+    new IValueParameter<T> ProblemDataParameter { get; }
+    new T ProblemData { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisProblemData.cs	(revision 16097)
@@ -0,0 +1,46 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisProblemData : INamedItem {
+    bool IsEmpty { get; }
+
+    Dataset Dataset { get; }
+    ICheckedItemList<StringValue> InputVariables { get; }
+    IEnumerable<string> AllowedInputVariables { get; }
+
+    IntRange TrainingPartition { get; }
+    IntRange TestPartition { get; }
+
+    IEnumerable<int> TrainingIndices { get; }
+    IEnumerable<int> TestIndices { get; }
+
+    bool IsTrainingSample(int index);
+    bool IsTestSample(int index);
+
+    event EventHandler Changed;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDataAnalysisSolution.cs	(revision 16097)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDataAnalysisSolution : INamedItem, IStorableContent {
+    IDataAnalysisModel Model { get; }
+    IDataAnalysisProblemData ProblemData { get; set; }
+
+    event EventHandler ModelChanged;
+    event EventHandler ProblemDataChanged;
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IDependencyCalculator.cs	(revision 16097)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IDependencyCalculator {
+    double Maximum { get; }
+    double Minimum { get; }
+    string Name { get; }
+
+    double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/IOnlineCalculator.cs	(revision 16097)
@@ -0,0 +1,46 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using System;
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Flags]
+  public enum OnlineCalculatorError {
+    /// <summary>
+    /// No error occurred
+    /// </summary>
+    None = 0,
+    /// <summary>
+    /// An invalid value has been added (often +/- Infinity and NaN are invalid values)
+    /// </summary>
+    InvalidValueAdded = 1,
+    /// <summary>
+    /// The number of elements added to the evaluator is not sufficient to calculate the result value
+    /// </summary>
+    InsufficientElementsAdded = 2
+  }
+  public interface IOnlineCalculator {
+    OnlineCalculatorError ErrorState { get; }
+    double Value { get; }
+    void Reset();
+    void Add(double original, double estimated);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleModel.cs	(revision 16097)
@@ -0,0 +1,30 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionEnsembleModel : IRegressionModel {
+    void Add(IRegressionModel model);
+    void Remove(IRegressionModel model);
+    IEnumerable<IRegressionModel> Models { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionEnsembleSolution.cs	(revision 16097)
@@ -0,0 +1,31 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using HeuristicLab.Core;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionEnsembleSolution : IRegressionSolution {
+    new IRegressionEnsembleModel Model { get; }
+    new RegressionEnsembleProblemData ProblemData { get; set; }
+    IItemCollection<IRegressionSolution> RegressionSolutions { get; }
+    IEnumerable<IEnumerable<double>> GetEstimatedValueVectors(Dataset dataset, IEnumerable<int> rows);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionModel.cs	(revision 16097)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionModel : IDataAnalysisModel {
+    IEnumerable<double> GetEstimatedValues(Dataset dataset, IEnumerable<int> rows);
+    IRegressionSolution CreateRegressionSolution(IRegressionProblemData problemData);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblem.cs	(revision 16097)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionProblem : IDataAnalysisProblem<IRegressionProblemData> {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionProblemData.cs	(revision 16097)
@@ -0,0 +1,26 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionProblemData : IDataAnalysisProblemData {
+    string TargetVariable { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/Regression/IRegressionSolution.cs	(revision 16097)
@@ -0,0 +1,44 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IRegressionSolution : IDataAnalysisSolution {
+    new IRegressionModel Model { get; }
+    new IRegressionProblemData ProblemData { get; set; }
+
+    IEnumerable<double> EstimatedValues { get; }
+    IEnumerable<double> EstimatedTrainingValues { get; }
+    IEnumerable<double> EstimatedTestValues { get; }
+    IEnumerable<double> GetEstimatedValues(IEnumerable<int> rows);
+
+    double TrainingMeanSquaredError { get; }
+    double TestMeanSquaredError { get; }
+    double TrainingMeanAbsoluteError { get; }
+    double TestMeanAbsoluteError { get; }
+    double TrainingRSquared { get; }
+    double TestRSquared { get; }
+    double TrainingRelativeError { get; }
+    double TestRelativeError { get; }
+    double TrainingNormalizedMeanSquaredError { get; }
+    double TestNormalizedMeanSquaredError { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/IOnlineTimeSeriesCalculator.cs	(revision 16097)
@@ -0,0 +1,33 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface IOnlineTimeSeriesCalculator {
+    OnlineCalculatorError ErrorState { get; }
+    double Value { get; }
+    void Reset();
+    void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisModel.cs	(revision 16097)
@@ -0,0 +1,28 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisModel : IRegressionModel {
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(Dataset dataset, IEnumerable<int> rows, IEnumerable<int> horizons);
+    ITimeSeriesPrognosisSolution CreateTimeSeriesPrognosisSolution(ITimeSeriesPrognosisProblemData problemData);
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblem.cs	(revision 16097)
@@ -0,0 +1,25 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisProblem : IDataAnalysisProblem<ITimeSeriesPrognosisProblemData> {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisProblemData.cs	(revision 16097)
@@ -0,0 +1,27 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisProblemData : IRegressionProblemData {
+    int TrainingHorizon { get; set; }
+    int TestHorizon { get; set; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Interfaces/TimeSeriesPrognosis/ITimeSeriesPrognosisSolution.cs	(revision 16097)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+namespace HeuristicLab.Problems.DataAnalysis {
+  public interface ITimeSeriesPrognosisSolution : IRegressionSolution {
+    new ITimeSeriesPrognosisModel Model { get; }
+    new ITimeSeriesPrognosisProblemData ProblemData { get; set; }
+
+    IEnumerable<IEnumerable<double>> GetPrognosedValues(IEnumerable<int> rows, IEnumerable<int> horizon);
+
+    double TrainingTheilsUStatisticAR1 { get; }
+    double TestTheilsUStatisticAR1 { get; }
+    double TrainingTheilsUStatisticMean { get; }
+    double TestTheilsUStatisticMean { get; }
+    double TrainingDirectionalSymmetry { get; }
+    double TestDirectionalSymmetry { get; }
+    double TrainingWeightedDirectionalSymmetry { get; }
+    double TestWeightedDirectionalSymmetry { get; }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/AutoCorrelationCalculator.cs	(revision 16097)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis.OnlineCalculators {
+  public class AutoCorrelationCalculator {
+    public static double[] Calculate(double[] values, out OnlineCalculatorError error) {
+      error = OnlineCalculatorError.None;
+      if (values.Any(x => double.IsNaN(x) || double.IsInfinity(x))) {
+        error = OnlineCalculatorError.InvalidValueAdded;
+        return new double[0];
+      }
+
+      double[] correlations = new double[values.Length];
+      alglib.corr.corrr1dcircular(values, values.Length, values, values.Length, ref correlations);
+      return correlations;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/HoeffdingsDependenceCalculator.cs	(revision 16097)
@@ -0,0 +1,139 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class HoeffdingsDependenceCalculator : IDependencyCalculator {
+
+    public double Maximum { get { return 1.0; } }
+
+    public double Minimum { get { return -0.5; } }
+
+    public string Name { get { return "Hoeffdings Dependence"; } }
+
+    public double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      return HoeffdingsDependenceCalculator.CalculateHoeffdings(originalValues, estimatedValues, out errorState);
+    }
+
+    public static double CalculateHoeffdings(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      double d = HoeffD(originalValues, estimatedValues, out errorState);
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+      return d;
+    }
+
+    /// <summary>
+    /// computes Hoeffding's dependence coefficient. 
+    /// Source: hoeffd.r from R package hmisc http://cran.r-project.org/web/packages/Hmisc/index.html
+    /// </summary>
+    private static double HoeffD(IEnumerable<double> xs, IEnumerable<double> ys, out OnlineCalculatorError errorState) {
+      double[] rx = TiedRank(xs);
+      double[] ry = TiedRank(ys);
+      if (rx.Length != ry.Length) throw new ArgumentException("The number of elements in xs and ys does not match");
+      double[] rxy = TiedRank(xs, ys);
+
+      int n = rx.Length;
+      double q = 0, r = 0, s = 0;
+      double scaling = 1.0 / (n * (n - 1));
+      for (int i = 0; i < n; i++) {
+        q += (rx[i] - 1) * (rx[i] - 2) * (ry[i] - 1) * (ry[i] - 2) * scaling;
+        r += (rx[i] - 2) * (ry[i] - 2) * rxy[i] * scaling;
+        s += rxy[i] * (rxy[i] - 1) * scaling;
+      }
+      errorState = OnlineCalculatorError.None;
+      // return 30.0 * (q - 2 * (n - 2) * r + (n - 2) * (n - 3) * s) / n / (n - 1) / (n - 2) / (n - 3) / (n - 4);
+      double t0 = q / (n - 2) / (n - 3) / (n - 4);
+      double t1 = 2 * r / (n - 3) / (n - 4);
+      double t2 = s / (n - 4);
+      return 30.0 * (t0 - t1 + t2);
+    }
+
+    private static double[] TiedRank(IEnumerable<double> xs) {
+      var xsArr = xs.ToArray();
+      var idx = Enumerable.Range(1, xsArr.Length).ToArray();
+      Array.Sort(xsArr, idx);
+      CRank(xsArr);
+      Array.Sort(idx, xsArr);
+      return xsArr;
+    }
+
+    /// <summary>
+    /// Calculates the joint rank with midranks for ties. Source: hoeffd.r from R package hmisc http://cran.r-project.org/web/packages/Hmisc/index.html
+    /// </summary>
+    /// <param name="xs"></param>
+    /// <param name="ys"></param>
+    /// <returns></returns>
+    private static double[] TiedRank(IEnumerable<double> xs, IEnumerable<double> ys) {
+      var xsArr = xs.ToArray();
+      var ysArr = ys.ToArray();
+      var r = new double[xsArr.Length];
+      int n = r.Length;
+      for (int i = 0; i < n; i++) {
+        var xi = xsArr[i];
+        var yi = ysArr[i];
+        double ri = 0.0;
+        for (int j = 0; j < n; j++) {
+          if (i != j) {
+            double cx;
+            if (xsArr[j] < xi) cx = 1.0;
+            else if (xsArr[j] > xi) cx = 0.0;
+            else cx = 0.5;  // eq
+            double cy;
+            if (ysArr[j] < yi) cy = 1.0;
+            else if (ysArr[j] > yi) cy = 0.0;
+            else cy = 0.5; // eq
+            ri = ri + cx * cy;
+          }
+        }
+        r[i] = ri;
+      }
+      return r;
+    }
+
+    /// <summary>
+    /// Calculates midranks. Source: Numerical Recipes in C. p 642
+    /// </summary>
+    /// <param name="w">Sorted array of elements, replaces the elements by their rank, including midranking of ties</param>
+    /// <returns></returns>
+    private static void CRank(double[] w) {
+      int i = 0;
+      int n = w.Length;
+      while (i < n - 1) {
+        if (w[i + 1] > w[i]) {    // w[i+1] must be larger or equal w[i] as w must be sorted
+          // not a tie
+          w[i] = i + 1;
+          i++;
+        } else {
+          int j;
+          for (j = i + 1; j < n && w[j] <= w[i]; j++) ; // how far does it go (<= effectively means == as w must be sorted, side-step equality for double values)
+          double rank = 1 + 0.5 * (i + j - 1);
+          int k;
+          for (k = i; k < j; k++) w[k] = rank; // set the rank for all tied entries
+          i = j;
+        }
+      }
+
+      if (i == n - 1) w[n - 1] = n;   // if the last element was not tied, this is its rank
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRDependenceCalculator.cs	(revision 16097)
@@ -0,0 +1,38 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class PearsonsRDependenceCalculator : IDependencyCalculator {
+
+    public double Maximum { get { return 1.0; } }
+
+    public double Minimum { get { return -1.0; } }
+
+    public string Name { get { return "Pearsons R"; } }
+
+    public double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      return Math.Sqrt(OnlinePearsonsRSquaredCalculator.Calculate(originalValues, estimatedValues, out errorState));
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/PearsonsRSquaredDependenceCalculator.cs	(revision 16097)
@@ -0,0 +1,37 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class PearsonsRSquaredDependenceCalculator : IDependencyCalculator {
+
+    public double Maximum { get { return 1.0; } }
+
+    public double Minimum { get { return 0.0; } }
+
+    public string Name { get { return "Pearsons R Squared"; } }
+
+    public double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      return OnlinePearsonsRSquaredCalculator.Calculate(originalValues, estimatedValues, out errorState);
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/DependencyCalculator/SpearmansRankCorrelationCoefficientCalculator.cs	(revision 16097)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class SpearmansRankCorrelationCoefficientCalculator : IDependencyCalculator {
+
+    public double Maximum { get { return 1.0; } }
+
+    public double Minimum { get { return -1.0; } }
+
+    public string Name { get { return "Spearmans Rank"; } }
+
+    public double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      return SpearmansRankCorrelationCoefficientCalculator.CalculateSpearmansRank(originalValues, estimatedValues, out errorState);
+    }
+
+    public static double CalculateSpearmansRank(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      double rs = double.NaN;
+      try {
+        var original = originalValues.ToArray();
+        var estimated = estimatedValues.ToArray();
+        rs = alglib.basestat.spearmancorr2(original, estimated, original.Length);
+        errorState = OnlineCalculatorError.None;
+      }
+      catch (alglib.alglibexception) {
+        errorState = OnlineCalculatorError.InvalidValueAdded;
+      }
+
+      return rs;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/NormalizedGiniCalculator.cs	(revision 16097)
@@ -0,0 +1,64 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class NormalizedGiniCalculator {
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      var originalValuesArr = originalValues.ToArray();
+      var estimatedValuesArr = estimatedValues.ToArray();
+      if (originalValuesArr.Count() != estimatedValuesArr.Count()) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      }
+      double oe = Gini(originalValuesArr, estimatedValuesArr, out errorState);
+      if (errorState != OnlineCalculatorError.None) return double.NaN;
+
+      return oe / (Gini(originalValuesArr, originalValuesArr, out errorState));
+    }
+
+    private static double Gini(IEnumerable<double> original, IEnumerable<double> estimated, out OnlineCalculatorError errorState) {
+      var pairs =
+        estimated.Zip(original, (e, o) => new { e, o })
+          .OrderByDescending(p => p.e);
+      if (pairs.Any()) errorState = OnlineCalculatorError.None;
+      else errorState = OnlineCalculatorError.InsufficientElementsAdded;
+      double giniSum = 0.0;
+      double sumOriginal = 0.0;
+      int n = 0;
+      foreach (var p in pairs) {
+        if (double.IsNaN(p.o) || double.IsNaN(p.e)) {
+          errorState = OnlineCalculatorError.InvalidValueAdded;
+          return double.NaN;
+        }
+        sumOriginal += p.o;
+        giniSum += sumOriginal;
+        n++;
+      }
+      giniSum /= sumOriginal;
+
+      return (giniSum - ((n + 1) / 2.0)) / n;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineAccuracyCalculator.cs	(revision 16097)
@@ -0,0 +1,93 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineAccuracyCalculator : IOnlineCalculator {
+
+    private int correctlyClassified;
+    private int n;
+    public double Accuracy {
+      get {
+        return correctlyClassified / (double)n;
+      }
+    }
+
+    public OnlineAccuracyCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return Accuracy; }
+    }
+    public void Reset() {
+      n = 0;
+      correctlyClassified = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      // ignore cases where original is NaN completly 
+      if (!double.IsNaN(original)) {
+        // increment number of observed samples
+        n++;
+        if (original.IsAlmost(estimated)) {
+          // original = estimated = +Inf counts as correctly classified
+          // original = estimated = -Inf counts as correctly classified
+          correctlyClassified++;
+        }
+        errorState = OnlineCalculatorError.None; // number of (non-NaN) samples >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineAccuracyCalculator accuracyCalculator = new OnlineAccuracyCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        accuracyCalculator.Add(original, estimated);
+        if (accuracyCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (accuracyCalculator.ErrorState == OnlineCalculatorError.None &&
+          (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = accuracyCalculator.ErrorState;
+        return accuracyCalculator.Accuracy;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineBoundedMeanSquaredErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,99 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineBoundedMeanSquaredErrorCalculator : IOnlineCalculator {
+
+    private double errorSum;
+    private int n;
+    public double BoundedMeanSquaredError {
+      get {
+        return n > 0 ? errorSum / n : 0.0;
+      }
+    }
+
+    public double LowerBound { get; private set; }
+    public double UpperBound { get; private set; }
+
+
+    public OnlineBoundedMeanSquaredErrorCalculator(double lowerBound, double upperbound) {
+      LowerBound = lowerBound;
+      UpperBound = upperbound;
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return BoundedMeanSquaredError; }
+    }
+    public void Reset() {
+      n = 0;
+      errorSum = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        if (estimated < LowerBound || estimated > UpperBound)
+          errorSum += Math.Abs(error);
+        else
+          errorSum += error * error;
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, double lowerBound, double upperBound, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineBoundedMeanSquaredErrorCalculator boundedMseCalculator = new OnlineBoundedMeanSquaredErrorCalculator(lowerBound, upperBound);
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        boundedMseCalculator.Add(original, estimated);
+        if (boundedMseCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (boundedMseCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = boundedMseCalculator.ErrorState;
+        return boundedMseCalculator.BoundedMeanSquaredError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineCovarianceCalcualtor.cs	(revision 16097)
@@ -0,0 +1,97 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineCovarianceCalculator : IOnlineCalculator {
+
+    private double xMean, yMean, Cn;
+    private int n;
+    public double Covariance {
+      get {
+        return n > 0 ? Cn / n : 0.0;
+      }
+    }
+
+    public OnlineCovarianceCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return Covariance; }
+    }
+    public void Reset() {
+      n = 0;
+      Cn = 0.0;
+      xMean = 0.0;
+      yMean = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double x, double y) {
+      if (double.IsNaN(y) || double.IsInfinity(y) || double.IsNaN(x) || double.IsInfinity(x) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+
+        // online calculation of tMean
+        xMean = xMean + (x - xMean) / n;
+        double delta = y - yMean; // delta = (y - yMean(n-1))
+        yMean = yMean + delta / n;
+
+        // online calculation of covariance
+        Cn = Cn + delta * (x - xMean); // C(n) = C(n-1) + (y - yMean(n-1)) (t - tMean(n))       
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
+      IEnumerator<double> firstEnumerator = first.GetEnumerator();
+      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+      OnlineCovarianceCalculator covarianceCalculator = new OnlineCovarianceCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
+        double x = secondEnumerator.Current;
+        double y = firstEnumerator.Current;
+        covarianceCalculator.Add(x, y);
+        if (covarianceCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (covarianceCalculator.ErrorState == OnlineCalculatorError.None &&
+          (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+      } else {
+        errorState = covarianceCalculator.ErrorState;
+        return covarianceCalculator.Covariance;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineDirectionalSymmetryCalculator.cs	(revision 16097)
@@ -0,0 +1,119 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
+    private int n;
+    private int nCorrect;
+
+    public double DirectionalSymmetry {
+      get {
+        if (n < 1) return 0.0;
+        return (double)nCorrect / n;
+      }
+    }
+
+    public OnlineDirectionalSymmetryCalculator() {
+      Reset();
+    }
+
+    public double Value {
+      get { return DirectionalSymmetry; }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        double prevActual = startValue;
+        double prevPredicted = startValue;
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // count a prediction correct if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - prevActual) * (predicted - prevPredicted) > 0.0 ||
+                (actual - prevActual).IsAlmost(predicted - prevPredicted)
+              ) {
+              nCorrect++;
+            }
+            n++;
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+    public void Reset() {
+      n = 0;
+      nCorrect = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
+      dsCalculator.Add(startValue, actualContinuation, predictedContinuation);
+      errorState = dsCalculator.ErrorState;
+      return dsCalculator.DirectionalSymmetry;
+    }
+    
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+      OnlineDirectionalSymmetryCalculator dsCalculator = new OnlineDirectionalSymmetryCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        dsCalculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (dsCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (dsCalculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = dsCalculator.ErrorState;
+        return dsCalculator.DirectionalSymmetry;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineLinearScalingParameterCalculator.cs	(revision 16097)
@@ -0,0 +1,120 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineLinearScalingParameterCalculator {
+
+    /// <summary>
+    /// Additive constant
+    /// </summary>
+    public double Alpha {
+      get {
+        return targetMeanCalculator.Mean - Beta * originalMeanAndVarianceCalculator.Mean;
+      }
+    }
+
+    /// <summary>
+    /// Multiplicative factor
+    /// </summary>
+    public double Beta {
+      get {
+        if (originalMeanAndVarianceCalculator.PopulationVariance.IsAlmost(0.0))
+          return 1;
+        else
+          return originalTargetCovarianceCalculator.Covariance / originalMeanAndVarianceCalculator.PopulationVariance;
+      }
+    }
+
+    public OnlineCalculatorError ErrorState {
+      get {
+        return targetMeanCalculator.MeanErrorState | originalMeanAndVarianceCalculator.MeanErrorState |
+          originalMeanAndVarianceCalculator.PopulationVarianceErrorState | originalTargetCovarianceCalculator.ErrorState;
+      }
+    }
+
+    private OnlineMeanAndVarianceCalculator targetMeanCalculator;
+    private OnlineMeanAndVarianceCalculator originalMeanAndVarianceCalculator;
+    private OnlineCovarianceCalculator originalTargetCovarianceCalculator;
+
+    public OnlineLinearScalingParameterCalculator() {
+      targetMeanCalculator = new OnlineMeanAndVarianceCalculator();
+      originalMeanAndVarianceCalculator = new OnlineMeanAndVarianceCalculator();
+      originalTargetCovarianceCalculator = new OnlineCovarianceCalculator();
+      Reset();
+    }
+
+    public void Reset() {
+      targetMeanCalculator.Reset();
+      originalMeanAndVarianceCalculator.Reset();
+      originalTargetCovarianceCalculator.Reset();
+    }
+
+    /// <summary>
+    /// Calculates linear scaling parameters in one pass.
+    /// The formulas to calculate the scaling parameters were taken from Scaled Symblic Regression by Maarten Keijzer.
+    /// http://www.springerlink.com/content/x035121165125175/
+    /// </summary>
+    public void Add(double original, double target) {
+      // validity of values is checked in mean calculator and covariance calculator
+      targetMeanCalculator.Add(target);
+      originalMeanAndVarianceCalculator.Add(original);
+      originalTargetCovarianceCalculator.Add(original, target);
+
+    }
+
+    /// <summary>
+    /// Calculates alpha and beta parameters to linearly scale elements of original to the scale and location of target
+    /// original[i] * beta + alpha
+    /// </summary>
+    /// <param name="original">Values that should be scaled</param>
+    /// <param name="target">Target values to which the original values should be scaled</param>
+    /// <param name="alpha">Additive constant for the linear scaling</param>
+    /// <param name="beta">Multiplicative factor for the linear scaling</param>
+    /// <param name="errorState">Flag that indicates if errors occurred in the calculation of the linea scaling parameters.</param>
+    public static void Calculate(IEnumerable<double> original, IEnumerable<double> target, out double alpha, out double beta, out OnlineCalculatorError errorState) {
+      OnlineLinearScalingParameterCalculator calculator = new OnlineLinearScalingParameterCalculator();
+      IEnumerator<double> originalEnumerator = original.GetEnumerator();
+      IEnumerator<double> targetEnumerator = target.GetEnumerator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & targetEnumerator.MoveNext()) {
+        double originalElement = originalEnumerator.Current;
+        double targetElement = targetEnumerator.Current;
+        calculator.Add(originalElement, targetElement);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+            (originalEnumerator.MoveNext() || targetEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in original and target enumeration do not match.");
+      } else {
+        errorState = calculator.ErrorState;
+        alpha = calculator.Alpha;
+        beta = calculator.Beta;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMaxAbsoluteErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,91 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMaxAbsoluteErrorCalculator : IOnlineCalculator {
+
+    private double mae;
+    private int n;
+    public double MaxAbsoluteError {
+      get {
+        return n > 0 ? mae : 0.0;
+      }
+    }
+
+    public OnlineMaxAbsoluteErrorCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return MaxAbsoluteError; }
+    }
+    public void Reset() {
+      n = 0;
+      mae = double.MinValue;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = Math.Abs(estimated - original);
+        if (error > mae)
+          mae = error;
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMaxAbsoluteErrorCalculator maeCalculator = new OnlineMaxAbsoluteErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        maeCalculator.Add(original, estimated);
+        if (maeCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (maeCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = maeCalculator.ErrorState;
+        return maeCalculator.MaxAbsoluteError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsoluteErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,90 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanAbsoluteErrorCalculator : IOnlineCalculator {
+
+    private double sae;
+    private int n;
+    public double MeanAbsoluteError {
+      get {
+        return n > 0 ? sae / n : 0.0;
+      }
+    }
+
+    public OnlineMeanAbsoluteErrorCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return MeanAbsoluteError; }
+    }
+    public void Reset() {
+      n = 0;
+      sae = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        sae += Math.Abs(error);
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMeanAbsoluteErrorCalculator maeCalculator = new OnlineMeanAbsoluteErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        maeCalculator.Add(original, estimated);
+        if (maeCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (maeCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = maeCalculator.ErrorState;
+        return maeCalculator.MeanAbsoluteError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAbsolutePercentageErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanAbsolutePercentageErrorCalculator : IOnlineCalculator {
+
+    private double sre;
+    private int n;
+    public double MeanAbsolutePercentageError {
+      get {
+        return n > 0 ? sre / n : 0.0;
+      }
+    }
+
+    public OnlineMeanAbsolutePercentageErrorCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return MeanAbsolutePercentageError; }
+    }
+    public void Reset() {
+      n = 0;
+      sre = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) ||
+        original.IsAlmost(0.0)) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        sre += Math.Abs((estimated - original) / original);
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMeanAbsolutePercentageErrorCalculator calculator = new OnlineMeanAbsolutePercentageErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        calculator.Add(original, estimated);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+            (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and second estimatedValues doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.MeanAbsolutePercentageError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanAndVarianceCalculator.cs	(revision 16097)
@@ -0,0 +1,109 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanAndVarianceCalculator {
+
+    private double m_oldM, m_newM, m_oldS, m_newS;
+    private int n;
+
+    private OnlineCalculatorError varianceErrorState;
+    public OnlineCalculatorError VarianceErrorState {
+      get { return varianceErrorState; }
+    }
+
+    public double Variance {
+      get {
+        return (n > 1) ? m_newS / (n - 1) : 0.0;
+      }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError PopulationVarianceErrorState {
+      get { return errorState; }
+    }
+    public double PopulationVariance {
+      get {
+        return (n > 0) ? m_newS / n : 0.0;
+      }
+    }
+
+    public OnlineCalculatorError MeanErrorState {
+      get { return errorState; }
+    }
+    public double Mean {
+      get {
+        return (n > 0) ? m_newM : 0.0;
+      }
+    }
+
+    public int Count {
+      get { return n; }
+    }
+
+    public OnlineMeanAndVarianceCalculator() {
+      Reset();
+    }
+
+    public void Reset() {
+      n = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+      varianceErrorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double x) {
+      if (double.IsNaN(x) || double.IsInfinity(x) || x > 1E13 || x < -1E13 || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        varianceErrorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        n++;
+        // See Knuth TAOCP vol 2, 3rd edition, page 232
+        if (n == 1) {
+          m_oldM = m_newM = x;
+          m_oldS = 0.0;
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+        } else {
+
+          varianceErrorState = varianceErrorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 2
+          m_newM = m_oldM + (x - m_oldM) / n;
+          m_newS = m_oldS + (x - m_oldM) * (x - m_newM);
+
+          // set up for next iteration
+          m_oldM = m_newM;
+          m_oldS = m_newS;
+        }
+      }
+    }
+
+    public static void Calculate(IEnumerable<double> x, out double mean, out double variance, out OnlineCalculatorError meanErrorState, out OnlineCalculatorError varianceErrorState) {
+      OnlineMeanAndVarianceCalculator meanAndVarianceCalculator = new OnlineMeanAndVarianceCalculator();
+      foreach (double xi in x) {
+        meanAndVarianceCalculator.Add(xi);
+      }
+      mean = meanAndVarianceCalculator.Mean;
+      variance = meanAndVarianceCalculator.Variance;
+      meanErrorState = meanAndVarianceCalculator.MeanErrorState;
+      varianceErrorState = meanAndVarianceCalculator.VarianceErrorState;
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,77 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanErrorCalculator : IOnlineCalculator {
+
+    private readonly OnlineMeanAndVarianceCalculator meanAndVarianceCalculator;
+    public double MeanError {
+      get { return meanAndVarianceCalculator.Mean; }
+    }
+
+    public OnlineMeanErrorCalculator() {
+      meanAndVarianceCalculator = new OnlineMeanAndVarianceCalculator();
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    public OnlineCalculatorError ErrorState {
+      get { return meanAndVarianceCalculator.MeanErrorState; }
+    }
+    public double Value {
+      get { return MeanError; }
+    }
+    public void Reset() {
+      meanAndVarianceCalculator.Reset();
+    }
+
+    public void Add(double original, double estimated) {
+      meanAndVarianceCalculator.Add(estimated - original);
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMeanErrorCalculator meCalculator = new OnlineMeanErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        meCalculator.Add(original, estimated);
+        if (meCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (meCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = meCalculator.ErrorState;
+        return meCalculator.MeanError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineMeanSquaredErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,90 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineMeanSquaredErrorCalculator : IOnlineCalculator {
+
+    private double sse;
+    private int n;
+    public double MeanSquaredError {
+      get {
+        return n > 0 ? sse / n : 0.0;
+      }
+    }
+
+    public OnlineMeanSquaredErrorCalculator() {
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+    public double Value {
+      get { return MeanSquaredError; }
+    }
+    public void Reset() {
+      n = 0;
+      sse = 0.0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public void Add(double original, double estimated) {
+      if (double.IsNaN(estimated) || double.IsInfinity(estimated) ||
+          double.IsNaN(original) || double.IsInfinity(original) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        double error = estimated - original;
+        sse += error * error;
+        n++;
+        errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded);        // n >= 1
+      }
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineMeanSquaredErrorCalculator mseCalculator = new OnlineMeanSquaredErrorCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        mseCalculator.Add(original, estimated);
+        if (mseCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (mseCalculator.ErrorState == OnlineCalculatorError.None &&
+         (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumerations doesn't match.");
+      } else {
+        errorState = mseCalculator.ErrorState;
+        return mseCalculator.MeanSquaredError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineNormalizedMeanSquaredErrorCalculator.cs	(revision 16097)
@@ -0,0 +1,95 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineNormalizedMeanSquaredErrorCalculator : IOnlineCalculator {
+    private OnlineMeanAndVarianceCalculator meanSquaredErrorCalculator;
+    private OnlineMeanAndVarianceCalculator originalVarianceCalculator;
+
+    public double NormalizedMeanSquaredError {
+      get {
+        double var = originalVarianceCalculator.Variance;
+        double m = meanSquaredErrorCalculator.Mean;
+        return var > 0 ? m / var : 0.0;
+      }
+    }
+
+    public OnlineNormalizedMeanSquaredErrorCalculator() {
+      meanSquaredErrorCalculator = new OnlineMeanAndVarianceCalculator();
+      originalVarianceCalculator = new OnlineMeanAndVarianceCalculator();
+      Reset();
+    }
+
+    #region IOnlineCalculator Members
+    public OnlineCalculatorError ErrorState {
+      get { return meanSquaredErrorCalculator.MeanErrorState | originalVarianceCalculator.VarianceErrorState; }
+    }
+    public double Value {
+      get { return NormalizedMeanSquaredError; }
+    }
+
+    public void Reset() {
+      meanSquaredErrorCalculator.Reset();
+      originalVarianceCalculator.Reset();
+    }
+
+    public void Add(double original, double estimated) {
+      // no need to check for validity of values explicitly as it is checked in the meanAndVariance calculator anyway
+      double error = estimated - original;
+      meanSquaredErrorCalculator.Add(error * error);
+      originalVarianceCalculator.Add(original);
+    }
+    #endregion
+
+    public static double Calculate(IEnumerable<double> originalValues, IEnumerable<double> estimatedValues, out OnlineCalculatorError errorState) {
+      IEnumerator<double> originalEnumerator = originalValues.GetEnumerator();
+      IEnumerator<double> estimatedEnumerator = estimatedValues.GetEnumerator();
+      OnlineNormalizedMeanSquaredErrorCalculator normalizedMSECalculator = new OnlineNormalizedMeanSquaredErrorCalculator();
+
+      //needed because otherwise the normalizedMSECalculator is in ErrorState.InsufficientValuesAdded
+      if (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        normalizedMSECalculator.Add(original, estimated);
+      }
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (originalEnumerator.MoveNext() & estimatedEnumerator.MoveNext()) {
+        double original = originalEnumerator.Current;
+        double estimated = estimatedEnumerator.Current;
+        normalizedMSECalculator.Add(original, estimated);
+        if (normalizedMSECalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (normalizedMSECalculator.ErrorState == OnlineCalculatorError.None &&
+           (estimatedEnumerator.MoveNext() || originalEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in originalValues and estimatedValues enumeration doesn't match.");
+      } else {
+        errorState = normalizedMSECalculator.ErrorState;
+        return normalizedMSECalculator.NormalizedMeanSquaredError;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlinePearsonsRSquaredCalculator.cs	(revision 16097)
@@ -0,0 +1,92 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlinePearsonsRSquaredCalculator : IOnlineCalculator {
+    private OnlineCovarianceCalculator covCalculator = new OnlineCovarianceCalculator();
+    private OnlineMeanAndVarianceCalculator sxCalculator = new OnlineMeanAndVarianceCalculator();
+    private OnlineMeanAndVarianceCalculator syCalculator = new OnlineMeanAndVarianceCalculator();
+
+    public double RSquared {
+      get {
+        double xVar = sxCalculator.PopulationVariance;
+        double yVar = syCalculator.PopulationVariance;
+        if (xVar.IsAlmost(0.0) || yVar.IsAlmost(0.0)) {
+          return 0.0;
+        } else {
+          double r = covCalculator.Covariance / (Math.Sqrt(xVar) * Math.Sqrt(yVar));
+          return r * r;
+        }
+      }
+    }
+
+    public OnlinePearsonsRSquaredCalculator() { }
+
+    #region IOnlineCalculator Members
+    public OnlineCalculatorError ErrorState {
+      get { return covCalculator.ErrorState | sxCalculator.PopulationVarianceErrorState | syCalculator.PopulationVarianceErrorState; }
+    }
+    public double Value {
+      get { return RSquared; }
+    }
+    public void Reset() {
+      covCalculator.Reset();
+      sxCalculator.Reset();
+      syCalculator.Reset();
+    }
+
+    public void Add(double x, double y) {
+      // no need to check validity of values explicitly here as it is checked in all three evaluators 
+      covCalculator.Add(x, y);
+      sxCalculator.Add(x);
+      syCalculator.Add(y);
+    }
+
+    #endregion
+
+    public static double Calculate(IEnumerable<double> first, IEnumerable<double> second, out OnlineCalculatorError errorState) {
+      IEnumerator<double> firstEnumerator = first.GetEnumerator();
+      IEnumerator<double> secondEnumerator = second.GetEnumerator();
+      OnlinePearsonsRSquaredCalculator rSquaredCalculator = new OnlinePearsonsRSquaredCalculator();
+
+      // always move forward both enumerators (do not use short-circuit evaluation!)
+      while (firstEnumerator.MoveNext() & secondEnumerator.MoveNext()) {
+        double original = firstEnumerator.Current;
+        double estimated = secondEnumerator.Current;
+        rSquaredCalculator.Add(original, estimated);
+        if (rSquaredCalculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if both enumerators are at the end to make sure both enumerations have the same length
+      if (rSquaredCalculator.ErrorState == OnlineCalculatorError.None &&
+           (secondEnumerator.MoveNext() || firstEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in first and second enumeration doesn't match.");
+      } else {
+        errorState = rSquaredCalculator.ErrorState;
+        return rSquaredCalculator.RSquared;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineTheilsUStatisticCalculator.cs	(revision 16097)
@@ -0,0 +1,128 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineTheilsUStatisticCalculator : IOnlineTimeSeriesCalculator {
+    private OnlineMeanAndVarianceCalculator squaredErrorMeanCalculator;
+    private OnlineMeanAndVarianceCalculator unbiasedEstimatorMeanCalculator;
+
+    public double TheilsUStatistic {
+      get {
+        return Math.Sqrt(squaredErrorMeanCalculator.Mean) / Math.Sqrt(unbiasedEstimatorMeanCalculator.Mean);
+      }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState | squaredErrorMeanCalculator.MeanErrorState | unbiasedEstimatorMeanCalculator.MeanErrorState; }
+    }
+
+    public OnlineTheilsUStatisticCalculator() {
+      squaredErrorMeanCalculator = new OnlineMeanAndVarianceCalculator();
+      unbiasedEstimatorMeanCalculator = new OnlineMeanAndVarianceCalculator();
+      Reset();
+    }
+
+    #region IOnlineEvaluator Members
+    public double Value {
+      get { return TheilsUStatistic; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      throw new NotSupportedException();
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        var referenceEnumerator = referenceContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & referenceEnumerator.MoveNext()
+          & ErrorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          double reference = referenceEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted) || double.IsNaN(reference)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            // error of predicted change
+            double errorPredictedChange = (predicted - startValue) - (actual - startValue);
+            squaredErrorMeanCalculator.Add(errorPredictedChange * errorPredictedChange);
+
+            double errorReference = (reference - startValue) - (actual - startValue);
+            unbiasedEstimatorMeanCalculator.Add(errorReference * errorReference);
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext() || referenceEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+
+    public void Reset() {
+      squaredErrorMeanCalculator.Reset();
+      unbiasedEstimatorMeanCalculator.Reset();
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    #endregion
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> referenceContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
+      calculator.Add(startValue, actualContinuation, referenceContinuation, predictedContinuation);
+      errorState = calculator.ErrorState;
+      return calculator.TheilsUStatistic;
+    }
+
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> referenceContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> referenceContinuationsEnumerator = referenceContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+
+      OnlineTheilsUStatisticCalculator calculator = new OnlineTheilsUStatisticCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & referenceContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, referenceContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || referenceContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations, referenceContinuation and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.TheilsUStatistic;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/OnlineCalculators/OnlineWeightedDirectionalSymmetryCalculator.cs	(revision 16097)
@@ -0,0 +1,121 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  public class OnlineWeightedDirectionalSymmetryCalculator : IOnlineTimeSeriesCalculator {
+    private int n;
+    private double correctSum;
+    private double incorrectSum;
+
+    public double WeightedDirectionalSymmetry {
+      get {
+        if (n <= 1) return 0.0;
+        return incorrectSum / correctSum;
+      }
+    }
+
+    public OnlineWeightedDirectionalSymmetryCalculator() {
+      Reset();
+    }
+
+    public double Value {
+      get { return WeightedDirectionalSymmetry; }
+    }
+
+    private OnlineCalculatorError errorState;
+    public OnlineCalculatorError ErrorState {
+      get { return errorState; }
+    }
+
+    public void Add(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation) {
+      if (double.IsNaN(startValue) || (errorState & OnlineCalculatorError.InvalidValueAdded) > 0) {
+        errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+      } else {
+        var actualEnumerator = actualContinuation.GetEnumerator();
+        var predictedEnumerator = predictedContinuation.GetEnumerator();
+        while (actualEnumerator.MoveNext() & predictedEnumerator.MoveNext() & errorState != OnlineCalculatorError.InvalidValueAdded) {
+          double actual = actualEnumerator.Current;
+          double predicted = predictedEnumerator.Current;
+          if (double.IsNaN(actual) || double.IsNaN(predicted)) {
+            errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+          } else {
+            double err = Math.Abs(actual - predicted);
+            // count as correct only if the trend (positive/negative/no change) is predicted correctly
+            if ((actual - startValue) * (predicted - startValue) > 0.0 ||
+              (actual - startValue).IsAlmost(predicted - startValue)) {
+              correctSum += err;
+            } else {
+              incorrectSum += err;
+            }
+            n++;
+          }
+        }
+        // check if both enumerators are at the end to make sure both enumerations have the same length
+        if (actualEnumerator.MoveNext() || predictedEnumerator.MoveNext()) {
+          errorState = errorState | OnlineCalculatorError.InvalidValueAdded;
+        } else {
+          errorState = errorState & (~OnlineCalculatorError.InsufficientElementsAdded); // n >= 1
+        }
+      }
+    }
+
+    public void Reset() {
+      n = 0;
+      correctSum = 0;
+      incorrectSum = 0;
+      errorState = OnlineCalculatorError.InsufficientElementsAdded;
+    }
+
+    public static double Calculate(double startValue, IEnumerable<double> actualContinuation, IEnumerable<double> predictedContinuation, out OnlineCalculatorError errorState) {
+      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
+      calculator.Add(startValue, actualContinuation, predictedContinuation);
+      errorState = calculator.ErrorState;
+      return calculator.WeightedDirectionalSymmetry;
+    }
+
+    public static double Calculate(IEnumerable<double> startValues, IEnumerable<IEnumerable<double>> actualContinuations, IEnumerable<IEnumerable<double>> predictedContinuations, out OnlineCalculatorError errorState) {
+      IEnumerator<double> startValueEnumerator = startValues.GetEnumerator();
+      IEnumerator<IEnumerable<double>> actualContinuationsEnumerator = actualContinuations.GetEnumerator();
+      IEnumerator<IEnumerable<double>> predictedContinuationsEnumerator = predictedContinuations.GetEnumerator();
+      OnlineWeightedDirectionalSymmetryCalculator calculator = new OnlineWeightedDirectionalSymmetryCalculator();
+
+      // always move forward all enumerators (do not use short-circuit evaluation!)
+      while (startValueEnumerator.MoveNext() & actualContinuationsEnumerator.MoveNext() & predictedContinuationsEnumerator.MoveNext()) {
+        calculator.Add(startValueEnumerator.Current, actualContinuationsEnumerator.Current, predictedContinuationsEnumerator.Current);
+        if (calculator.ErrorState != OnlineCalculatorError.None) break;
+      }
+
+      // check if all enumerators are at the end to make sure both enumerations have the same length
+      if (calculator.ErrorState == OnlineCalculatorError.None &&
+          (startValueEnumerator.MoveNext() || actualContinuationsEnumerator.MoveNext() || predictedContinuationsEnumerator.MoveNext())) {
+        throw new ArgumentException("Number of elements in startValues, actualContinuations and estimatedValues predictedContinuations doesn't match.");
+      } else {
+        errorState = calculator.ErrorState;
+        return calculator.WeightedDirectionalSymmetry;
+      }
+    }
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Plugin.cs.frame	(revision 16097)
@@ -0,0 +1,42 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Problems.DataAnalysis {
+  [Plugin("HeuristicLab.Problems.DataAnalysis","Provides base classes for data analysis tasks.", "3.4.3.$WCREV$")]
+  [PluginFile("HeuristicLab.Problems.DataAnalysis-3.4.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.ALGLIB","3.6")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  public class HeuristicLabProblemsDataAnalysisPlugin : PluginBase {
+  }
+}
Index: /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/HeuristicLab.Problems.DataAnalysis/3.4/Properties/AssemblyInfo.cs.frame	(revision 16097)
@@ -0,0 +1,55 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Problems.DataAnalysis")]
+[assembly: AssemblyDescription("Provides base classes for data analysis tasks.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("460C6FC6-FFBB-4286-B781-06D9F56A202D")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.3.$WCREV$")]
Index: /branches/1776_ClassificationEnsembleVoting/PreBuildEvent.cmd
===================================================================
--- /branches/1776_ClassificationEnsembleVoting/PreBuildEvent.cmd	(revision 16097)
+++ /branches/1776_ClassificationEnsembleVoting/PreBuildEvent.cmd	(revision 16097)
@@ -0,0 +1,2 @@
+IF EXIST "%ProjectDir%\Properties\AssemblyInfo.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Properties\AssemblyInfo.cs.frame" "%ProjectDir%\Properties\AssemblyInfo.cs"
+IF EXIST "%ProjectDir%\Plugin.cs.frame" SubWCRev "%ProjectDir%\" "%ProjectDir%\Plugin.cs.frame" "%ProjectDir%\Plugin.cs"
