Index: /branches/2780_SAPBA/Build.cmd
===================================================================
--- /branches/2780_SAPBA/Build.cmd	(revision 16108)
+++ /branches/2780_SAPBA/Build.cmd	(revision 16108)
@@ -0,0 +1,104 @@
+@ECHO OFF
+
+SET CLEANBEFOREBUILD=
+
+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 :clean
+
+:prompt_platform
+SET /P PLATFORM=Which platform to build [Any CPU]: 
+IF "%PLATFORM%"=="" SET PLATFORM=Any CPU
+
+:clean
+IF "%~4"=="" GOTO :prompt_clean
+
+SET CLEANBEFOREBUILD=%~4
+GOTO :main
+
+:prompt_clean
+SET /P CLEANBEFOREBUILD=Would you like to clean before building [n]: 
+IF "%CLEANBEFOREBUILD%"=="" SET CLEANBEFOREBUILD=n
+
+: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%" NEQ "n" (
+  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:Build /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/2780_SAPBA/HeuristicLab.Algorithms.SAPBA.sln
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA.sln	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA.sln	(revision 16108)
@@ -0,0 +1,22 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.SAPBA-3.4", "HeuristicLab.Algorithms.SAPBA\HeuristicLab.Algorithms.SAPBA-3.4.csproj", "{F740AF15-7ADA-40D9-B225-837F4E4F41E0}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F740AF15-7ADA-40D9-B225-837F4E4F41E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F740AF15-7ADA-40D9-B225-837F4E4F41E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F740AF15-7ADA-40D9-B225-837F4E4F41E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F740AF15-7ADA-40D9-B225-837F4E4F41E0}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/EgoUtilities.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/EgoUtilities.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/EgoUtilities.cs	(revision 16108)
@@ -0,0 +1,177 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Threading;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  internal static class EgoUtilities {
+    //Extention methods for convenience
+    public static int ArgMax<T>(this IEnumerable<T> values, Func<T, double> func) {
+      var max = double.MinValue;
+      var maxIdx = 0;
+      var idx = 0;
+      foreach (var v in values) {
+        var d = func.Invoke(v);
+        if (d > max) {
+          max = d;
+          maxIdx = idx;
+        }
+        idx++;
+      }
+      return maxIdx;
+    }
+    public static int ArgMin<T>(this IEnumerable<T> values, Func<T, double> func) {
+      return ArgMax(values, x => -func.Invoke(x));
+    }
+    public static double GetEstimation(this IRegressionModel model, RealVector r) {
+      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
+      return model.GetEstimatedValues(dataset, new[] { 0 }).First();
+    }
+    public static double GetVariance(this IConfidenceRegressionModel model, RealVector r) {
+      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
+      return model.GetEstimatedVariances(dataset, new[] { 0 }).First();
+    }
+    public static double GetDoubleValue(this IDataset dataset, int i, int j) {
+      return dataset.GetDoubleValue("input" + j, i);
+    }
+
+    //Sub-Algorithms
+    public static ResultCollection SyncRunSubAlgorithm(IAlgorithm alg, int random) {
+
+      if (alg.Parameters.ContainsKey("SetSeedRandomly") && alg.Parameters.ContainsKey("Seed")) {
+        var setSeed = alg.Parameters["SetSeedRandomly"].ActualValue as BoolValue;
+        var seed = alg.Parameters["Seed"].ActualValue as IntValue;
+        if (seed == null || setSeed == null) throw new ArgumentException("wrong SeedParametertypes");
+        setSeed.Value = false;
+        seed.Value = random;
+
+      }
+
+
+      EventWaitHandle trigger = new AutoResetEvent(false);
+      Exception ex = null;
+      EventHandler<EventArgs<Exception>> exhandler = (sender, e) => ex = e.Value;
+      EventHandler stoppedHandler = (sender, e) => trigger.Set();
+      alg.ExceptionOccurred += exhandler;
+      alg.Stopped += stoppedHandler;
+      alg.Prepare();
+      alg.Start();
+      trigger.WaitOne();
+      alg.ExceptionOccurred -= exhandler;
+      alg.Stopped -= stoppedHandler;
+      if (ex != null) throw ex;
+      return alg.Results;
+    }
+
+    public static IRegressionSolution BuildModel(CancellationToken cancellationToken, IEnumerable<Tuple<RealVector, double>> samples, IDataAnalysisAlgorithm<IRegressionProblem> regressionAlgorithm, IRandom random, bool removeDuplicates = true, IRegressionSolution oldSolution = null) {
+      var dataset = GetDataSet(samples.ToList(), removeDuplicates);
+      var problemdata = new RegressionProblemData(dataset, dataset.VariableNames.Where(x => !x.Equals("output")), "output");
+      problemdata.TrainingPartition.Start = 0;
+      problemdata.TrainingPartition.End = dataset.Rows;
+      problemdata.TestPartition.Start = dataset.Rows;
+      problemdata.TestPartition.End = dataset.Rows;
+
+
+      if (regressionAlgorithm.Problem == null) regressionAlgorithm.Problem = new RegressionProblem();
+      var problem = regressionAlgorithm.Problem;
+      problem.ProblemDataParameter.Value = problemdata;
+      var i = 0;
+      IRegressionSolution solution = null;
+
+      while (solution == null && i++ < 100) {
+        var results = EgoUtilities.SyncRunSubAlgorithm(regressionAlgorithm, random.Next(int.MaxValue));
+        solution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
+        cancellationToken.ThrowIfCancellationRequested();
+      }
+
+      //special treatement for GaussianProcessRegression
+      var gp = regressionAlgorithm;
+      var oldGaussian = oldSolution as GaussianProcessRegressionSolution;
+      if (gp != null && oldGaussian != null) {
+        const double noise = 0.0;
+        var n = samples.First().Item1.Length;
+        var mean = (IMeanFunction)oldGaussian.Model.MeanFunction.Clone();
+        var cov = (ICovarianceFunction)oldGaussian.Model.CovarianceFunction.Clone();
+        if (mean.GetNumberOfParameters(n) != 0 || cov.GetNumberOfParameters(n) != 0) throw new ArgumentException("DEBUG: assumption about fixed paramters wrong");
+        double[] hyp = { noise };
+        try {
+          var model = new GaussianProcessModel(problemdata.Dataset, problemdata.TargetVariable, problemdata.AllowedInputVariables, problemdata.TrainingIndices, hyp, mean, cov);
+          model.FixParameters();
+          var sol = new GaussianProcessRegressionSolution(model, problemdata);
+          if (solution == null || solution.TrainingMeanSquaredError > sol.TrainingMeanSquaredError) {
+            solution = sol;
+          }
+        }
+        catch (ArgumentException) { }
+      }
+
+      if (solution == null) throw new ArgumentException("The algorithm didn't return a model");
+      regressionAlgorithm.Runs.Clear();
+      return solution;
+    }
+    //RegressionModel extensions
+    public const double DuplicateResolution = 0.0001;
+    public static Dataset GetDataSet(IReadOnlyList<Tuple<RealVector, double>> samples, bool removeDuplicates) {
+      if (removeDuplicates) samples = RemoveDuplicates(samples); //TODO duplicate removal leads to incorrect uncertainty values in models
+      var dimensions = samples[0].Item1.Length + 1;
+      var data = new double[samples.Count, dimensions];
+      var names = new string[dimensions - 1];
+      for (var i = 0; i < names.Length; i++) names[i] = "input" + i;
+      for (var j = 0; j < samples.Count; j++) {
+        for (var i = 0; i < names.Length; i++) data[j, i] = samples[j].Item1[i];
+        data[j, dimensions - 1] = samples[j].Item2;
+      }
+      return new Dataset(names.Concat(new[] { "output" }).ToArray(), data);
+    }
+    private static IReadOnlyList<Tuple<RealVector, double>> RemoveDuplicates(IReadOnlyList<Tuple<RealVector, double>> samples) {
+      var res = new List<Tuple<RealVector, double, int>>();
+      foreach (var sample in samples) {
+        if (res.Count == 0) {
+          res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
+          continue;
+        }
+        var index = res.ArgMin(x => Euclidian(sample.Item1, x.Item1));
+        var d = Euclidian(res[index].Item1, sample.Item1);
+        if (d > DuplicateResolution)
+          res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
+        else {
+          var t = res[index];
+          res.RemoveAt(index);
+          res.Add(new Tuple<RealVector, double, int>(t.Item1, t.Item2 + sample.Item2, t.Item3 + 1));
+        }
+      }
+      return res.Select(x => new Tuple<RealVector, double>(x.Item1, x.Item2 / x.Item3)).ToArray();
+    }
+    private static double Euclidian(IEnumerable<double> a, IEnumerable<double> b) {
+      return Math.Sqrt(a.Zip(b, (d, d1) => d - d1).Sum(d => d * d));
+    }
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj	(revision 16108)
@@ -0,0 +1,158 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{F740AF15-7ADA-40D9-B225-837F4E4F41E0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.SAPBA</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.SAPBA-3.4</AssemblyName>
+    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\trunk\sources\bin\</OutputPath>
+    <DefineConstants>TRACE;DEBUG;CODE_ANALYSIS</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Algorithms.CMAEvolutionStrategy-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.CMAEvolutionStrategy-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.EvolutionStrategy-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.EvolutionStrategy-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Collections-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Data-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec" />
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.DataAnalysis.Views-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="EgoUtilities.cs" />
+    <Compile Include="Strategies\IndividualStrategy.cs" />
+    <Compile Include="Strategies\GenerationalStrategy.cs" />
+    <Compile Include="SurrogateAssistedPopulationBasedAlgorithm.cs" />
+    <Compile Include="Interfaces\ISurrogateStrategy.cs" />
+    <Compile Include="Interfaces\ISurrogateAlgorithm.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Problems\SurrogateProblem.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Strategies\StrategyBase.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Plugin.cs.frame" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup />
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd
+</PreBuildEvent>
+  </PropertyGroup>
+  <!-- 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>
+  -->
+</Project>
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj.user
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj.user	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj.user	(revision 16108)
@@ -0,0 +1,7 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
+    <StartAction>Program</StartAction>
+    <StartProgram>..\..\..\..\HL\trunk\sources\bin\HeuristicLab 3.3.exe</StartProgram>
+  </PropertyGroup>
+</Project>
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateAlgorithm.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateAlgorithm.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateAlgorithm.cs	(revision 16108)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Optimization;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  public interface ISurrogateAlgorithm<in T> : IAlgorithm where T : IDeepCloneable {
+    void SetInitialSamples(T[] solutions, double[] qualities);
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs	(revision 16108)
@@ -0,0 +1,34 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Threading;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  public interface ISurrogateStrategy : IItem {
+    double Evaluate(RealVector r, IRandom random);
+    void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random);
+    void Initialize(SurrogateAssistedPopulationBasedAlgorithm algorithm);
+    void UpdateCancellation(CancellationToken cancellationToken);
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(revision 16108)
@@ -0,0 +1,30 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.SAPBA.Operators {
+  [Item("FixedRealVectorCreator", "An operator which creates a new real vector cloned from a single Point")]
+  [StorableClass]
+  public class FixedRealVectorCreator : RealVectorCreator, IStrategyParameterCreator {
+    [Storable]
+    private RealVector Point;
+
+    [StorableConstructor]
+    protected FixedRealVectorCreator(bool deserializing) : base(deserializing) { }
+    protected FixedRealVectorCreator(FixedRealVectorCreator original, Cloner cloner) : base(original, cloner) {
+      Point = cloner.Clone(original.Point);
+    }
+    public FixedRealVectorCreator(RealVector r) : base() {
+      Point = r;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new FixedRealVectorCreator(this, cloner); }
+    protected override RealVector Create(IRandom random, IntValue length, DoubleMatrix bounds) {
+      return (RealVector)Point.Clone();
+    }
+  }
+
+}
+
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs	(revision 16108)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Algorithms.SAPBA {
+  [Plugin("HeuristicLab.Algorithms.SAPBA", "3.4.5.14893")]
+  [PluginFile("HeuristicLab.Algorithms.SAPBA-3.4.dll", PluginFileType.Assembly)]
+  [PluginFile("displayModelFrame.html", PluginFileType.Data)]
+  [PluginDependency("HeuristicLab.Algorithms.CMAEvolutionStrategy", "3.4")]
+  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
+  [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.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators","3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Parameters","3.3")]
+  [PluginDependency("HeuristicLab.Persistence","3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabProblemsDataAnalysisSymbolicViewsPlugin : PluginBase {
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame	(revision 16108)
@@ -0,0 +1,49 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2013 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.Algorithms.SAPBA {
+  [Plugin("HeuristicLab.Algorithms.SAPBA", "3.4.5.$WCREV$")]
+  [PluginFile("HeuristicLab.Algorithms.SAPBA-3.4.dll", PluginFileType.Assembly)]
+  [PluginFile("displayModelFrame.html", PluginFileType.Data)]
+  [PluginDependency("HeuristicLab.Algorithms.CMAEvolutionStrategy", "3.4")]
+  [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
+  [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.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators","3.3")]
+  [PluginDependency("HeuristicLab.Optimization","3.3")]
+  [PluginDependency("HeuristicLab.Parameters","3.3")]
+  [PluginDependency("HeuristicLab.Persistence","3.3")]
+  [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabProblemsDataAnalysisSymbolicViewsPlugin : PluginBase {
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/PreBuildEvent.cmd
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/PreBuildEvent.cmd	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/PreBuildEvent.cmd	(revision 16108)
@@ -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"
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs	(revision 16108)
@@ -0,0 +1,46 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  [StorableClass]
+  [Item("Surrogate problem (single-objective)", "Wrapper for a problem that allows surrogate models to mitigate some of the work")]
+  public class SurrogateProblem : SingleObjectiveBasicProblem<RealVectorEncoding> {
+
+    [Storable]
+    private ISurrogateStrategy Strategy;
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected SurrogateProblem(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() { }
+    protected SurrogateProblem(SurrogateProblem original, Cloner cloner) : base(original, cloner) {
+      Strategy = original?.Strategy;
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new SurrogateProblem(this, cloner); }
+    public SurrogateProblem() {
+    }
+    #endregion
+
+    public override double Evaluate(Individual individual, IRandom random) {
+      return Strategy.Evaluate(individual.RealVector(), random);
+    }
+    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(individuals, qualities, results, random);
+      Strategy.Analyze(individuals, qualities, results, random);
+    }
+
+    public override bool Maximization { get; }
+
+    public void SetStrategy(ISurrogateStrategy strategy) {
+      Strategy = strategy;
+    }
+    public void SetProblem(SingleObjectiveBasicProblem<IEncoding> expensiveProblem) {
+      if (expensiveProblem != null) Encoding = expensiveProblem.Encoding as RealVectorEncoding;
+    }
+
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs	(revision 16108)
@@ -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.Algorithms.SAPBA")]
+[assembly: AssemblyDescription("HeuristicLab Efficient Global Optimization")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2017 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("0c41579a-d3c4-49fb-af7a-119eea1155ac")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.14893")]
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs.frame	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs.frame	(revision 16108)
@@ -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.Algorithms.SAPBA")]
+[assembly: AssemblyDescription("HeuristicLab Efficient Global Optimization")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2017 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("0c41579a-d3c4-49fb-af7a-119eea1155ac")]
+
+// 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 Build and Revision Numbers 
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.4.0.0")]
+[assembly: AssemblyFileVersion("3.4.0.$WCREV$")]
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs	(revision 16108)
@@ -0,0 +1,168 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Threading;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  internal static class SapbaUtilities {
+    //Extention methods for convenience
+    public static int ArgMax<T>(this IEnumerable<T> values, Func<T, double> func) {
+      var max = double.MinValue;
+      var maxIdx = 0;
+      var idx = 0;
+      foreach (var v in values) {
+        var d = func.Invoke(v);
+        if (d > max) {
+          max = d;
+          maxIdx = idx;
+        }
+        idx++;
+      }
+      return maxIdx;
+    }
+    public static int ArgMin<T>(this IEnumerable<T> values, Func<T, double> func) {
+      return ArgMax(values, x => -func.Invoke(x));
+    }
+    public static double GetEstimation(this IRegressionModel model, RealVector r) {
+      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
+      return model.GetEstimatedValues(dataset, new[] { 0 }).First();
+    }
+    public static double GetVariance(this IConfidenceRegressionModel model, RealVector r) {
+      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
+      return model.GetEstimatedVariances(dataset, new[] { 0 }).First();
+    }
+    public static double GetDoubleValue(this IDataset dataset, int i, int j) {
+      return dataset.GetDoubleValue("input" + j, i);
+    }
+
+    //Sub-Algorithms
+    public static ResultCollection SyncRunSubAlgorithm(IAlgorithm alg, int random) {
+      if (alg.Parameters.ContainsKey("SetSeedRandomly") && alg.Parameters.ContainsKey("Seed")) {
+        var setSeed = alg.Parameters["SetSeedRandomly"].ActualValue as BoolValue;
+        var seed = alg.Parameters["Seed"].ActualValue as IntValue;
+        if (seed == null || setSeed == null) throw new ArgumentException("wrong SeedParametertypes");
+        setSeed.Value = false;
+        seed.Value = random;
+
+      }
+      EventWaitHandle trigger = new AutoResetEvent(false);
+      Exception ex = null;
+      EventHandler<EventArgs<Exception>> exhandler = (sender, e) => ex = e.Value;
+      EventHandler stoppedHandler = (sender, e) => trigger.Set();
+      alg.ExceptionOccurred += exhandler;
+      alg.Stopped += stoppedHandler;
+      alg.Prepare();
+      alg.Start();
+      trigger.WaitOne();
+      alg.ExceptionOccurred -= exhandler;
+      alg.Stopped -= stoppedHandler;
+      if (ex != null) throw ex;
+      return alg.Results;
+    }
+    public static IRegressionSolution BuildModel(IReadOnlyList<Tuple<RealVector, double>> samples, IDataAnalysisAlgorithm<IRegressionProblem> regressionAlgorithm, IRandom random, bool removeDuplicates = true, IRegressionSolution oldSolution = null) {
+      var dataset = GetDataSet(samples, removeDuplicates);
+      var problemdata = new RegressionProblemData(dataset, dataset.VariableNames.Where(x => !x.Equals("output")), "output");
+      problemdata.TrainingPartition.Start = 0;
+      problemdata.TrainingPartition.End = dataset.Rows;
+      problemdata.TestPartition.Start = dataset.Rows;
+      problemdata.TestPartition.End = dataset.Rows;
+
+      if (regressionAlgorithm.Problem == null) regressionAlgorithm.Problem = new RegressionProblem();
+      var problem = regressionAlgorithm.Problem;
+      problem.ProblemDataParameter.Value = problemdata;
+      var i = 0;
+      IRegressionSolution solution = null;
+
+      while (solution == null && i++ < 100) {
+        var results = SyncRunSubAlgorithm(regressionAlgorithm, random.Next(int.MaxValue));
+        solution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
+      }
+
+      //special treatement for GaussianProcessRegression
+      var gp = regressionAlgorithm as GaussianProcessRegression;
+      var oldGaussian = oldSolution as GaussianProcessRegressionSolution;
+      if (gp != null && oldGaussian != null) {
+        const double noise = 0.0;
+        var n = samples.First().Item1.Length;
+        var mean = (IMeanFunction)oldGaussian.Model.MeanFunction.Clone();
+        var cov = (ICovarianceFunction)oldGaussian.Model.CovarianceFunction.Clone();
+        if (mean.GetNumberOfParameters(n) != 0 || cov.GetNumberOfParameters(n) != 0) throw new ArgumentException("DEBUG: assumption about fixed paramters wrong");
+        double[] hyp = { noise };
+        try {
+          var model = new GaussianProcessModel(problemdata.Dataset, problemdata.TargetVariable, problemdata.AllowedInputVariables, problemdata.TrainingIndices, hyp, mean, cov);
+          model.FixParameters();
+          var sol = new GaussianProcessRegressionSolution(model, problemdata);
+          if (solution == null || solution.TrainingMeanSquaredError > sol.TrainingMeanSquaredError) solution = sol;
+        }
+        catch (ArgumentException) { }
+      }
+      if (solution == null) throw new ArgumentException("The algorithm didn't return a model");
+      regressionAlgorithm.Runs.Clear();
+      return solution;
+    }
+
+    //RegressionModel extensions
+    public const double DuplicateResolution = 0.000001;
+    public static Dataset GetDataSet(IReadOnlyList<Tuple<RealVector, double>> samples, bool removeDuplicates) {
+      if (removeDuplicates) samples = RemoveDuplicates(samples); //TODO duplicate removal leads to incorrect uncertainty values in models
+      var dimensions = samples[0].Item1.Length + 1;
+      var data = new double[samples.Count, dimensions];
+      var names = new string[dimensions - 1];
+      for (var i = 0; i < names.Length; i++) names[i] = "input" + i;
+      for (var j = 0; j < samples.Count; j++) {
+        for (var i = 0; i < names.Length; i++) data[j, i] = samples[j].Item1[i];
+        data[j, dimensions - 1] = samples[j].Item2;
+      }
+      return new Dataset(names.Concat(new[] { "output" }).ToArray(), data);
+    }
+    private static IReadOnlyList<Tuple<RealVector, double>> RemoveDuplicates(IReadOnlyList<Tuple<RealVector, double>> samples) {
+      var res = new List<Tuple<RealVector, double, int>>();
+      foreach (var sample in samples) {
+        if (res.Count == 0) {
+          res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
+          continue;
+        }
+        var index = res.ArgMin(x => Euclidian(sample.Item1, x.Item1));
+        var d = Euclidian(res[index].Item1, sample.Item1);
+        if (d > DuplicateResolution) res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
+        else {
+          var t = res[index];
+          res.RemoveAt(index);
+          res.Add(new Tuple<RealVector, double, int>(t.Item1, t.Item2 + sample.Item2, t.Item3 + 1));
+        }
+      }
+      return res.Select(x => new Tuple<RealVector, double>(x.Item1, x.Item2 / x.Item3)).ToArray();
+    }
+    private static double Euclidian(IEnumerable<double> a, IEnumerable<double> b) {
+      return Math.Sqrt(a.Zip(b, (d, d1) => d - d1).Sum(d => d * d));
+    }
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/GenerationalStrategy.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/GenerationalStrategy.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/GenerationalStrategy.cs	(revision 16108)
@@ -0,0 +1,49 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.SAPBA.Strategies {
+  public class GenerationalStrategy : StrategyBase {
+    public const string NoGenerationsParameterName = "Number of generations";
+    public IFixedValueParameter<IntValue> NoGenerationsParameter => Parameters[NoGenerationsParameterName] as IFixedValueParameter<IntValue>;
+    public IntValue NoGenerations => NoGenerationsParameter.Value;
+    [Storable]
+    public int Generations;
+
+    #region Constructors
+    private GenerationalStrategy(GenerationalStrategy original, Cloner cloner) : base(original, cloner) {
+      Generations = original.Generations;
+    }
+    public GenerationalStrategy() {
+      Parameters.Add(new FixedValueParameter<IntValue>(NoGenerationsParameterName, "The number of generations before a new model is constructed", new IntValue(3)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GenerationalStrategy(this, cloner);
+    }
+    #endregion
+
+    public override double Evaluate(RealVector r, IRandom random) {
+      return EstimateSample(r, random).Item2;
+    }
+
+    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) {
+    }
+
+    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
+      if (RegressionSolution != null && Generations < NoGenerations.Value) Generations++;
+      else {
+        foreach (var indi in individuals) EvaluateSample(indi.RealVector(), random);
+        BuildRegressionSolution(random);
+        Generations = 0;
+      }
+    }
+
+    protected override void Initialize() {
+      Generations = 0;
+    }
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/IndividualStrategy.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/IndividualStrategy.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/IndividualStrategy.cs	(revision 16108)
@@ -0,0 +1,43 @@
+﻿using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Algorithms.SAPBA.Strategies {
+  public class IndividualStrategy : StrategyBase {
+    public const string SampledIndividualsParameterName = "SampledIndividals";
+    public IFixedValueParameter<IntValue> SampledIndividualsParameter => Parameters[SampledIndividualsParameterName] as IFixedValueParameter<IntValue>;
+    public IntValue SampledIndividuals => SampledIndividualsParameter.Value;
+
+    #region Constructors
+    private IndividualStrategy(IndividualStrategy original, Cloner cloner) : base(original, cloner) {
+    }
+    public IndividualStrategy() {
+      Parameters.Add(new FixedValueParameter<IntValue>(SampledIndividualsParameterName, "The number of individuals that are sampled each generation", new IntValue(3)));
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new IndividualStrategy(this, cloner);
+    }
+    #endregion
+
+    public override double Evaluate(RealVector r, IRandom random) {
+      return EstimateSample(r, random).Item2;
+    }
+
+    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) {
+    }
+
+    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
+      var samples = individuals.Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d)).OrderBy(t => Algorithm.Problem.Maximization ? -t.Item2 : t.Item2).Take(SampledIndividuals.Value).Select(t => t.Item1.RealVector());
+      foreach (var indi in samples) EvaluateSample(indi, random);
+      BuildRegressionSolution(random);
+    }
+
+    protected override void Initialize() {
+    }
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs	(revision 16108)
@@ -0,0 +1,113 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Algorithms.EGO;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  [StorableClass]
+  public class InfillStrategy : StrategyBase {
+    #region Parameternames
+    public const string NoGenerationsParameterName = "Number of generations";
+    public const string NoIndividualsParameterName = "Number of individuals";
+    public const string InfillCriterionParameterName = "InfillCriterion";
+    #endregion
+    #region Paramterproperties
+    public IFixedValueParameter<IntValue> NoGenerationsParameter => Parameters[NoGenerationsParameterName] as IFixedValueParameter<IntValue>;
+    public IFixedValueParameter<IntValue> NoIndividualsParameter => Parameters[NoIndividualsParameterName] as IFixedValueParameter<IntValue>;
+    public IConstrainedValueParameter<IInfillCriterion> InfillCriterionParameter => Parameters[InfillCriterionParameterName] as IConstrainedValueParameter<IInfillCriterion>;
+    #endregion
+    #region Properties
+    public IntValue NoGenerations => NoGenerationsParameter.Value;
+    public IntValue NoIndividuals => NoIndividualsParameter.Value;
+    public IInfillCriterion InfillCriterion => InfillCriterionParameter.Value;
+    [Storable]
+    public int Generations;
+    #endregion
+
+    #region Constructors
+    [StorableConstructor]
+    protected InfillStrategy(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      AttachListeners();
+    }
+    protected InfillStrategy(InfillStrategy original, Cloner cloner) : base(original, cloner) {
+      Generations = original.Generations;
+      AttachListeners();
+    }
+    public InfillStrategy() {
+      var critera = new ItemSet<IInfillCriterion> { new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuality(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
+      Parameters.Add(new FixedValueParameter<IntValue>(NoGenerationsParameterName, "The number of generations before a new model is constructed", new IntValue(3)));
+      Parameters.Add(new FixedValueParameter<IntValue>(NoIndividualsParameterName, "The number of individuals that are sampled each generation ", new IntValue(3)));
+      Parameters.Add(new ConstrainedValueParameter<IInfillCriterion>(InfillCriterionParameterName, "The infill criterion used to cheaply evaluate points.", critera, critera.First()));
+      AttachListeners();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new InfillStrategy(this, cloner);
+    }
+    #endregion
+
+    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) { }
+    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
+      if (RegressionSolution != null && Generations < NoGenerations.Value) Generations++;
+      else {
+        //Select NoIndividuals best samples
+        var samples = individuals
+          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
+          .OrderBy(t => Problem.Maximization ? -t.Item2 : t.Item2)
+          .Take(NoIndividuals.Value)
+          .Select(t => t.Item1.RealVector());
+        foreach (var indi in samples) EvaluateSample(indi, random);
+        BuildRegressionSolution(random);
+        Generations = 0;
+      }
+    }
+    protected override void Initialize() {
+      Generations = 0;
+    }
+
+    #region events
+    private void AttachListeners() {
+      ModelChanged += OnModelChanged;
+    }
+    private void OnModelChanged(object sender, EventArgs e) {
+      InfillCriterion.Encoding = Problem?.Encoding as RealVectorEncoding;
+      InfillCriterion.RegressionSolution = RegressionSolution;
+      InfillCriterion.ExpensiveMaximization = Problem?.Maximization ?? false;
+      if (RegressionSolution != null && InfillCriterion.Encoding != null)
+        InfillCriterion.Initialize();
+    }
+    #endregion
+
+    protected override double Estimate(RealVector point, IRandom random) {
+      return InfillCriterion.Maximization() != Maximization() ? -InfillCriterion.Evaluate(point) : InfillCriterion.Evaluate(point);
+    }
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs	(revision 16108)
@@ -0,0 +1,249 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Algorithms.DataAnalysis;
+using HeuristicLab.Algorithms.EGO;
+using HeuristicLab.Algorithms.SAPBA.Operators;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  [StorableClass]
+  public class LamarckianStrategy : InfillStrategy {
+    #region Parameternames
+    public const string NoTrainingPointsParameterName = "Number of Trainingpoints";
+    public const string LocalInfillCriterionParameterName = "LocalInfillCriterion";
+    public const string OptimizationAlgorithmParameterName = "Optimization Algorithm";
+    public const string RegressionAlgorithmParameterName = "Regression Algorithm";
+    #endregion
+    #region Parameters
+    public IFixedValueParameter<IntValue> NoTrainingPointsParameter => Parameters[NoTrainingPointsParameterName] as IFixedValueParameter<IntValue>;
+    public IValueParameter<IAlgorithm> OptimizationAlgorithmParameter => Parameters[OptimizationAlgorithmParameterName] as IValueParameter<IAlgorithm>;
+    public IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>> RegressionAlgorithmParameter => Parameters[RegressionAlgorithmParameterName] as IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>;
+    public IConstrainedValueParameter<IInfillCriterion> LocalInfillCriterionParameter => Parameters[LocalInfillCriterionParameterName] as IConstrainedValueParameter<IInfillCriterion>;
+    #endregion
+    #region Properties
+    public IntValue NoTrainingPoints => NoTrainingPointsParameter.Value;
+    public IAlgorithm OptimizationAlgorithm => OptimizationAlgorithmParameter.Value;
+    public IDataAnalysisAlgorithm<IRegressionProblem> RegressionAlgorithm => RegressionAlgorithmParameter.Value;
+    public IInfillCriterion LocalInfillCriterion => LocalInfillCriterionParameter.Value;
+    #endregion
+
+    #region Constructors
+    [StorableConstructor]
+    protected LamarckianStrategy(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterParameterEvents();
+    }
+    protected LamarckianStrategy(LamarckianStrategy original, Cloner cloner) : base(original, cloner) {
+      RegisterParameterEvents();
+    }
+    public LamarckianStrategy() {
+      var localCritera = new ItemSet<IInfillCriterion> { new ExpectedQuality(), new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
+      var osEs = new OffspringSelectionEvolutionStrategy.OffspringSelectionEvolutionStrategy {
+        Problem = new InfillProblem(),
+        ComparisonFactor = { Value = 1.0 },
+        MaximumGenerations = { Value = 1000 },
+        MaximumEvaluatedSolutions = { Value = 100000 },
+        PlusSelection = { Value = true },
+        PopulationSize = { Value = 1 }
+      };
+      osEs.MutatorParameter.Value = osEs.MutatorParameter.ValidValues.OfType<MultiRealVectorManipulator>().First();
+      Parameters.Add(new FixedValueParameter<IntValue>(NoTrainingPointsParameterName, "The number of sample points used to create a local model", new IntValue(50)));
+      Parameters.Add(new ConstrainedValueParameter<IInfillCriterion>(LocalInfillCriterionParameterName, "The infill criterion used to cheaply evaluate points.", localCritera, localCritera.First()));
+      Parameters.Add(new ValueParameter<IAlgorithm>(OptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", osEs));
+      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", new GaussianProcessRegression { Problem = new RegressionProblem() }));
+      RegisterParameterEvents();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LamarckianStrategy(this, cloner);
+    }
+    #endregion
+
+    //Short lived stores for analysis
+    private readonly List<double> LamarckValues = new List<double>();
+    private readonly List<double> SampleValues = new List<double>();
+
+    protected override void Initialize() {
+      base.Initialize();
+      var infillProblem = OptimizationAlgorithm.Problem as InfillProblem;
+      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm does not have an InfillProblem.");
+      infillProblem.InfillCriterion = LocalInfillCriterion;
+    }
+    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) {
+      base.Analyze(individuals, qualities, results, globalResults, random);
+      const string plotName = "Lamarck Comparison";
+      const string lamarckRow = "Lamarck Values";
+      const string samplesRow = "Original Values";
+      if (!globalResults.ContainsKey(plotName))
+        globalResults.Add(new Result(plotName, new DataTable(plotName)));
+
+      var plot = (DataTable)globalResults[plotName].Value;
+      if (!plot.Rows.ContainsKey(lamarckRow)) plot.Rows.Add(new DataRow(lamarckRow));
+      if (!plot.Rows.ContainsKey(samplesRow)) plot.Rows.Add(new DataRow(samplesRow));
+      plot.Rows[lamarckRow].Values.AddRange(LamarckValues);
+      plot.Rows[samplesRow].Values.AddRange(SampleValues);
+      LamarckValues.Clear();
+      SampleValues.Clear();
+
+      //analyze Hypervolumes 
+      const string volPlotName = "Hypervolumes Comparison";
+      const string mainRowName = "Population Volume (log)";
+      const string subspaceRowName = "Subspace Volume (log) for Lamarck Candidate ";
+      if (!globalResults.ContainsKey(volPlotName))
+        globalResults.Add(new Result(volPlotName, new DataTable(volPlotName)));
+
+      plot = (DataTable)globalResults[volPlotName].Value;
+      if (!plot.Rows.ContainsKey(mainRowName)) plot.Rows.Add(new DataRow(mainRowName));
+      var v = Math.Log(GetStableVolume(GetBoundingBox(individuals.Select(x => x.RealVector()))));
+      plot.Rows[mainRowName].Values.Add(v);
+
+      var indis = individuals
+          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
+          .OrderBy(t => SapbaAlgorithm.Problem.Maximization ? -t.Item2 : t.Item2)
+          .Take(NoIndividuals.Value)
+          .Select(t => t.Item1).ToArray();
+
+      for (var i = 0; i < indis.Length; i++) {
+        var samples = GetNearestSamples(NoTrainingPoints.Value, indis[i].RealVector());
+        var d = Math.Log(GetStableVolume(GetBoundingBox(samples.Select(x => x.Item1))));
+        if (!plot.Rows.ContainsKey(subspaceRowName + i)) plot.Rows.Add(new DataRow(subspaceRowName + i));
+        plot.Rows[subspaceRowName + i].Values.Add(d);
+      }
+
+
+
+    }
+    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
+      if (RegressionSolution == null) return;
+      if (Generations < NoGenerations.Value) Generations++;
+      else {
+        //Select best Individuals
+        var indis = individuals
+          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
+          .OrderBy(t => Problem.Maximization ? -t.Item2 : t.Item2)
+          .Take(NoIndividuals.Value)
+          .Select(t => t.Item1).ToArray();
+        //Evaluate individuals
+        foreach (var individual in indis)
+          SampleValues.Add(EvaluateSample(individual.RealVector(), random).Item2);
+
+        //Perform memetic replacement for all points
+        for (var i = 0; i < indis.Length; i++) {
+          var vector = indis[i].RealVector();
+          var altVector = OptimizeInfillProblem(vector, random);
+          LamarckValues.Add(EvaluateSample(altVector, random).Item2);
+          if (LamarckValues[i] < SampleValues[i] == Problem.Maximization) continue;
+          for (var j = 0; j < vector.Length; j++) vector[j] = altVector[j];
+        }
+
+        BuildRegressionSolution(random);
+        Generations = 0;
+      }
+    }
+
+    #region Events
+    private void RegisterParameterEvents() {
+      OptimizationAlgorithmParameter.ValueChanged += OnInfillAlgorithmChanged;
+      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
+      LocalInfillCriterionParameter.ValueChanged += OnInfillCriterionChanged;
+    }
+    private void OnInfillCriterionChanged(object sender, EventArgs e) {
+      ((InfillProblem)OptimizationAlgorithm.Problem).InfillCriterion = LocalInfillCriterion;
+    }
+    private void OnInfillAlgorithmChanged(object sender, EventArgs e) {
+      OptimizationAlgorithm.Problem = new InfillProblem { InfillCriterion = LocalInfillCriterion };
+      OptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged; //avoid double attaching
+      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
+    }
+    private void OnInfillProblemChanged(object sender, EventArgs e) {
+      OptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged;
+      OptimizationAlgorithm.Problem = new InfillProblem { InfillCriterion = LocalInfillCriterion };
+      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
+    }
+    #endregion
+
+    #region helpers
+    private RealVector OptimizeInfillProblem(RealVector point, IRandom random) {
+      var infillProblem = OptimizationAlgorithm.Problem as InfillProblem;
+      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm does not have an InfillProblem.");
+      if (infillProblem.InfillCriterion != LocalInfillCriterion) throw new ArgumentException("InfillCiriterion for Problem is not correctly set.");
+
+      var points = Math.Min(NoTrainingPoints.Value, Samples.Count);
+      var samples = GetNearestSamples(points, point);
+      var regression = SapbaUtilities.BuildModel(samples, RegressionAlgorithm, random);
+      var box = GetBoundingBox(samples.Select(x => x.Item1));
+
+      infillProblem.Encoding.Length = ((RealVectorEncoding)Problem.Encoding).Length;
+      infillProblem.Encoding.Bounds = box;
+      infillProblem.Encoding.SolutionCreator = new FixedRealVectorCreator(point);
+      infillProblem.Initialize(regression, Problem.Maximization);
+      var res = SapbaUtilities.SyncRunSubAlgorithm(OptimizationAlgorithm, random.Next(int.MaxValue));
+      if (!res.ContainsKey(InfillProblem.BestInfillSolutionResultName)) throw new ArgumentException("The InfillOptimizationAlgorithm did not return a best solution");
+      var v = res[InfillProblem.BestInfillSolutionResultName].Value as RealVector;
+      if (v == null) throw new ArgumentException("The InfillOptimizationAlgorithm did not return the expected result types");
+      if (!InBounds(v, box)) throw new ArgumentException("Vector not in bounds");
+      OptimizationAlgorithm.Runs.Clear();
+      return v;
+    }
+    private Tuple<RealVector, double>[] GetNearestSamples(int noSamples, RealVector point) {
+      return Samples.Select(sample => Tuple.Create(SquaredEuclidean(sample.Item1, point), sample)).OrderBy(x => x.Item1).Take(noSamples).Select(x => x.Item2).ToArray();
+    }
+    private static DoubleMatrix GetBoundingBox(IEnumerable<RealVector> samples) {
+      DoubleMatrix m = null;
+      foreach (var sample in samples)
+        if (m == null) {
+          m = new DoubleMatrix(sample.Length, 2);
+          for (var i = 0; i < sample.Length; i++) m[i, 0] = m[i, 1] = sample[i];
+        } else
+          for (var i = 0; i < sample.Length; i++) {
+            m[i, 0] = Math.Min(m[i, 0], sample[i]);
+            m[i, 1] = Math.Max(m[i, 1], sample[i]);
+          }
+      return m;
+    }
+
+    //the volume of a bounded-box whith slightly increased dimensions (Volume can never reach 0)
+    private static double GetStableVolume(DoubleMatrix bounds) {
+      var res = 1.0;
+      for (var i = 0; i < bounds.Rows; i++) res *= bounds[i, 1] - bounds[i, 0] + 0.1;
+      return res;
+    }
+    private static bool InBounds(RealVector r, DoubleMatrix bounds) {
+      return !r.Where((t, i) => t < bounds[i, 0] || t > bounds[i, 1]).Any();
+    }
+    private static double SquaredEuclidean(RealVector a, RealVector b) {
+      return a.Select((t, i) => t - b[i]).Sum(d => d * d);
+    }
+    #endregion
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs	(revision 16108)
@@ -0,0 +1,161 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Threading;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Algorithms.SAPBA.Strategies {
+  [StorableClass]
+  public abstract class StrategyBase : ParameterizedNamedItem, ISurrogateStrategy {
+    #region Properties
+    [Storable]
+    protected SurrogateAssistedPopulationBasedAlgorithm Algorithm;
+    [Storable]
+    private List<Tuple<RealVector, double>> Samples;
+    [Storable]
+    protected IRegressionSolution RegressionSolution;
+    protected CancellationToken Cancellation;
+    private IEnumerable<Tuple<RealVector, double>> TruncatedSamples => Samples.Count > Algorithm.MaximalDatasetSize && Algorithm.MaximalDatasetSize > 0 ? Samples.Skip(Samples.Count - Algorithm.MaximalDatasetSize) : Samples;
+    #endregion
+
+    #region ResultName
+    private const string BestQualityResultName = "Best Quality";
+    private const string BestSolutionResultName = "Best Solution";
+    private const string QualityTableResultName = "Qualities";
+    private const string BestQualityRowName = "Best Quality";
+    private const string WorstQualityRowName = "Worst Quality";
+    private const string CurrentQualityRowName = "Current Quality";
+    private const string MedianQualityRowName = "Median Quality";
+    private const string AverageQualityRowName = "Average Quality";
+    private const string RegressionSolutionResultName = "Model";
+    private const string EvaluatedSoultionsResultName = "EvaluatedSolutions";
+    private const string IterationsResultName = "Iterations";
+    #endregion
+
+    #region constructors
+    [StorableConstructor]
+    protected StrategyBase(bool deserializing) : base(deserializing) { }
+    protected StrategyBase(StrategyBase original, Cloner cloner) : base(original, cloner) {
+      if (original.Samples != null) Samples = original.Samples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
+      RegressionSolution = cloner.Clone(original.RegressionSolution);
+    }
+    protected StrategyBase() { }
+    #endregion
+
+    public abstract double Evaluate(RealVector r, IRandom random);
+    protected abstract void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random);
+    protected abstract void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random);
+    protected abstract void Initialize();
+
+    public void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+      Algorithm.Problem.Analyze(individuals, qualities, results, random);
+      ProcessPopulation(individuals, qualities, random);
+
+      var globalResults = Algorithm.Results;
+      if (!globalResults.ContainsKey(EvaluatedSoultionsResultName)) globalResults.Add(new Result(EvaluatedSoultionsResultName, new IntValue(Samples.Count)));
+      else ((IntValue)globalResults[EvaluatedSoultionsResultName].Value).Value = Samples.Count;
+      if (!globalResults.ContainsKey(IterationsResultName)) globalResults.Add(new Result(IterationsResultName, new IntValue(0)));
+      else ((IntValue)globalResults[IterationsResultName].Value).Value++;
+
+      if (Samples.Count != 0) {
+        var min = Samples.Min(x => x.Item2);
+        var max = Samples.Max(x => x.Item2);
+        var bestIdx = Algorithm.Problem.Maximization ? Samples.ArgMax(x => x.Item2) : Samples.ArgMin(x => x.Item2);
+
+        if (!globalResults.ContainsKey(BestQualityResultName)) globalResults.Add(new Result(BestQualityResultName, new DoubleValue(0.0)));
+        ((DoubleValue)globalResults[BestQualityResultName].Value).Value = Samples[bestIdx].Item2;
+        if (!globalResults.ContainsKey(BestSolutionResultName)) globalResults.Add(new Result(BestSolutionResultName, new RealVector()));
+        globalResults[BestSolutionResultName].Value = Samples[bestIdx].Item1;
+
+        DataTable table;
+        if (!globalResults.ContainsKey(QualityTableResultName)) {
+          table = new DataTable("Qualites", "Qualites over iteration");
+          globalResults.Add(new Result(QualityTableResultName, table));
+          table.Rows.Add(new DataRow(BestQualityRowName, "Best Quality"));
+          table.Rows.Add(new DataRow(WorstQualityRowName, "Worst Quality"));
+          table.Rows.Add(new DataRow(CurrentQualityRowName, "Current Quality"));
+          table.Rows.Add(new DataRow(MedianQualityRowName, "Median Quality"));
+          table.Rows.Add(new DataRow(AverageQualityRowName, "Average Quality"));
+        }
+        table = (DataTable)globalResults[QualityTableResultName].Value;
+        table.Rows[BestQualityResultName].Values.Add(Algorithm.Problem.Maximization ? max : min);
+        table.Rows[WorstQualityRowName].Values.Add(Algorithm.Problem.Maximization ? min : max);
+        table.Rows[CurrentQualityRowName].Values.Add(Samples[Samples.Count - 1].Item2);
+        table.Rows[AverageQualityRowName].Values.Add(Samples.Average(x => x.Item2));
+        table.Rows[MedianQualityRowName].Values.Add(Samples.Select(x => x.Item2).Median());
+      }
+
+      if (RegressionSolution != null) {
+        if (!globalResults.ContainsKey(RegressionSolutionResultName))
+          globalResults.Add(new Result(RegressionSolutionResultName, RegressionSolution));
+        else
+          globalResults[RegressionSolutionResultName].Value = RegressionSolution;
+      }
+
+      Analyze(individuals, qualities, results, globalResults, random);
+    }
+    public void Initialize(SurrogateAssistedPopulationBasedAlgorithm algorithm) {
+      Algorithm = algorithm;
+      Samples = algorithm.InitialSamples?.ToList() ?? new List<Tuple<RealVector, double>>();
+      RegressionSolution = null;
+      Initialize();
+    }
+
+    #region Helpers for Subclasses
+    protected void BuildRegressionSolution(IRandom random) {
+      RegressionSolution = EgoUtilities.BuildModel(Cancellation, TruncatedSamples, Algorithm.RegressionAlgorithm, random, Algorithm.RemoveDuplicates, RegressionSolution);
+    }
+    protected Tuple<RealVector, double> EvaluateSample(RealVector point, IRandom random) {
+      Cancellation.ThrowIfCancellationRequested();
+      if (Samples.Count >= Algorithm.MaximumEvaluations) { Algorithm.OptimizationAlgorithm.Stop(); return new Tuple<RealVector, double>(point, 0.0); }
+      var p = new Tuple<RealVector, double>(point, Algorithm.Problem.Evaluate(GetIndividual(point), random));
+      Samples.Add(p);
+      return p;
+    }
+    protected Tuple<RealVector, double> EstimateSample(RealVector point, IRandom random) {
+      if (Samples.Count == Algorithm.InitialEvaluations && RegressionSolution == null) BuildRegressionSolution(random);
+      return Samples.Count < Algorithm.InitialEvaluations ? EvaluateSample(point, random) : new Tuple<RealVector, double>(point, RegressionSolution.Model.GetEstimation(point));
+    }
+    #endregion
+
+    #region Helpers
+    private Individual GetIndividual(RealVector r) {
+      var scope = new Scope();
+      scope.Variables.Add(new Variable(Algorithm.Problem.Encoding.Name, r));
+      return new SingleEncodingIndividual(Algorithm.Problem.Encoding, scope);
+    }
+
+    public void UpdateCancellation(CancellationToken cancellationToken) {
+      Cancellation = cancellationToken;
+    }
+    #endregion
+  }
+}
Index: /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs
===================================================================
--- /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs	(revision 16108)
+++ /branches/2780_SAPBA/HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs	(revision 16108)
@@ -0,0 +1,202 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 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.Threading;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Algorithms.SAPBA.Strategies;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.SAPBA {
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.Algorithms, Priority = 95)]
+  [Item("SurrogateAssistedPopulationBasedAlgorithm", "")]
+  public class SurrogateAssistedPopulationBasedAlgorithm : BasicAlgorithm, ISurrogateAlgorithm<RealVector> {
+    #region Basic-Alg-Essentials
+    public override bool SupportsPause => true;
+    public override Type ProblemType => typeof(SingleObjectiveBasicProblem<IEncoding>);
+    public new SingleObjectiveBasicProblem<IEncoding> Problem
+    {
+      get { return (SingleObjectiveBasicProblem<IEncoding>)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region ParameterNames
+    private const string InitialEvaluationsParameterName = "Initial Evaluations";
+    private const string MaximalDataSetSizeParameterName = "Maximal Dataset Size";
+    private const string MaximumEvaluationsParameterName = "Maximum Evaluations";
+    private const string MaximumRuntimeParameterName = "Maximum Runtime";
+    private const string OptimizationAlgorithmParameterName = "Optimization Algorithm";
+    private const string RemoveDuplicatesParamterName = "RemoveDuplicates";
+    private const string RegressionAlgorithmParameterName = "RegressionAlgorithm";
+    private const string SeedParameterName = "Seed";
+    private const string SetSeedRandomlyParameterName = "SetSeedRandomly";
+    private const string StrategyParameterName = "Strategy";
+    #endregion
+
+    #region ParameterProperties
+    public IFixedValueParameter<IntValue> InitialEvaluationsParameter => Parameters[InitialEvaluationsParameterName] as IFixedValueParameter<IntValue>;
+    public IFixedValueParameter<IntValue> MaximalDataSetSizeParameter => Parameters[MaximalDataSetSizeParameterName] as IFixedValueParameter<IntValue>;
+    public IFixedValueParameter<IntValue> MaximumEvaluationsParameter => Parameters[MaximumEvaluationsParameterName] as IFixedValueParameter<IntValue>;
+    public IFixedValueParameter<IntValue> MaximumRuntimeParameter => Parameters[MaximumRuntimeParameterName] as IFixedValueParameter<IntValue>;
+    public IValueParameter<Algorithm> OptimizationAlgorithmParameter => Parameters[OptimizationAlgorithmParameterName] as IValueParameter<Algorithm>;
+    public IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>> RegressionAlgorithmParameter => Parameters[RegressionAlgorithmParameterName] as IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>;
+    public IFixedValueParameter<BoolValue> RemoveDuplicatesParameter => Parameters[RemoveDuplicatesParamterName] as IFixedValueParameter<BoolValue>;
+    public IFixedValueParameter<IntValue> SeedParameter => Parameters[SeedParameterName] as IFixedValueParameter<IntValue>;
+    public IFixedValueParameter<BoolValue> SetSeedRandomlyParameter => Parameters[SetSeedRandomlyParameterName] as IFixedValueParameter<BoolValue>;
+    public IConstrainedValueParameter<ISurrogateStrategy> StrategyParameter => Parameters[StrategyParameterName] as IConstrainedValueParameter<ISurrogateStrategy>;
+    #endregion
+
+    #region Properties
+    public int InitialEvaluations => InitialEvaluationsParameter.Value.Value;
+    public int MaximalDatasetSize => MaximalDataSetSizeParameter.Value.Value;
+    public int MaximumEvaluations => MaximumEvaluationsParameter.Value.Value;
+    public int MaximumRuntime => MaximumRuntimeParameter.Value.Value;
+    public Algorithm OptimizationAlgorithm => OptimizationAlgorithmParameter.Value;
+    public IDataAnalysisAlgorithm<IRegressionProblem> RegressionAlgorithm => RegressionAlgorithmParameter.Value;
+    public bool RemoveDuplicates => RemoveDuplicatesParameter.Value.Value;
+    public int Seed => SeedParameter.Value.Value;
+    public bool SetSeedRandomly => SetSeedRandomlyParameter.Value.Value;
+    public ISurrogateStrategy SurrogateStrategy => StrategyParameter.Value;
+    #endregion
+
+    #region StorableProperties 
+    [Storable]
+    private IRandom Random = new MersenneTwister();
+    [Storable]
+    public List<Tuple<RealVector, double>> InitialSamples { get; private set; }
+    [Storable]
+    public SurrogateProblem surrogateProblem;
+    public void SetInitialSamples(RealVector[] solutions, double[] qualities) {
+      InitialSamples = solutions.Zip(qualities, (vector, d) => new Tuple<RealVector, double>(vector, d)).ToList();
+    }
+    #endregion
+
+    #region HLConstructors
+    [StorableConstructor]
+    protected SurrogateAssistedPopulationBasedAlgorithm(bool deserializing) : base(deserializing) { }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeseialization() {
+      RegisterEventhandlers();
+    }
+    protected SurrogateAssistedPopulationBasedAlgorithm(SurrogateAssistedPopulationBasedAlgorithm original, Cloner cloner) : base(original, cloner) {
+      Random = cloner.Clone(Random);
+      if (original.InitialSamples != null) InitialSamples = original.InitialSamples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
+      RegisterEventhandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) { return new SurrogateAssistedPopulationBasedAlgorithm(this, cloner); }
+    public SurrogateAssistedPopulationBasedAlgorithm() {
+      surrogateProblem = new SurrogateProblem();
+      var geneticAlgorithm = new GeneticAlgorithm.GeneticAlgorithm {
+        PopulationSize = { Value = 50 },
+        Problem = surrogateProblem
+      };
+      var model = new GaussianProcessRegression {
+        Problem = new RegressionProblem()
+      };
+      model.CovarianceFunctionParameter.Value = new CovarianceRationalQuadraticIso();
+
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(int.MaxValue)));
+      Parameters.Add(new FixedValueParameter<IntValue>(InitialEvaluationsParameterName, "", new IntValue(10)));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeParameterName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(-1)));
+      Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", model));
+      Parameters.Add(new ValueParameter<Algorithm>(OptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", geneticAlgorithm));
+      Parameters.Add(new FixedValueParameter<IntValue>(MaximalDataSetSizeParameterName, "The maximum number of sample points used to generate the model. Set 0 or less to use always all samples ", new IntValue(-1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>(RemoveDuplicatesParamterName, "Wether duplicate samples should be replaced by a single sample with an averaged quality. This GREATLY decreases the chance of ill conditioned models (unbuildable models) but is not theoretically sound as the model ignores the increasing certainty in this region"));
+      var strategies = new ItemSet<ISurrogateStrategy> { new GenerationalStrategy(), new IndividualStrategy() };
+      Parameters.Add(new ConstrainedValueParameter<ISurrogateStrategy>(StrategyParameterName, "The surrogate strategy that dictates how the optimization alg is assisted", strategies, strategies.First()));
+      RegisterEventhandlers();
+    }
+    #endregion
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+      //encoding
+      var enc = Problem.Encoding as RealVectorEncoding;
+      if (enc == null) throw new ArgumentException("The SAPBA algorithm can only be applied to RealVectorEncodings");
+
+      //random
+      if (SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next();
+      Random.Reset(Seed);
+
+      //initialize Strategy and Problem
+      SurrogateStrategy.Initialize(this);
+      SurrogateStrategy.UpdateCancellation(cancellationToken);
+      surrogateProblem.SetStrategy(SurrogateStrategy);
+      surrogateProblem.SetProblem(Problem);
+    }
+    protected override void Run(CancellationToken cancellationToken) {
+      SurrogateStrategy.UpdateCancellation(cancellationToken);
+      try { EgoUtilities.SyncRunSubAlgorithm(OptimizationAlgorithm, Random.Next()); }
+      finally { Analyze(); }
+    }
+    private void Analyze() { }
+
+    #region Eventhandling
+    private void RegisterEventhandlers() {
+      DeregisterEventhandlers();
+      OptimizationAlgorithmParameter.ValueChanged += OnOptimizationAlgorithmChanged;
+    }
+    private void DeregisterEventhandlers() {
+      OptimizationAlgorithmParameter.ValueChanged -= OnOptimizationAlgorithmChanged;
+    }
+    private void OnOptimizationAlgorithmChanged(object sender, EventArgs e) {
+      OptimizationAlgorithm.Problem = surrogateProblem;
+    }
+
+    protected override void OnExecutionTimeChanged() {
+      base.OnExecutionTimeChanged();
+      if (CancellationTokenSource == null) return;
+      if (MaximumRuntime == -1) return;
+      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
+    }
+    public override void Pause() {
+      base.Pause();
+      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Pause();
+      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started) OptimizationAlgorithm.Pause();
+
+    }
+    public override void Stop() {
+      base.Stop();
+      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Stop();
+      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started) OptimizationAlgorithm.Stop();
+    }
+    protected override void OnProblemChanged() {
+      base.OnProblemChanged();
+      surrogateProblem.SetProblem(Problem);
+    }
+    #endregion
+
+  }
+}
Index: /branches/2780_SAPBA/PreBuildEvent.cmd
===================================================================
--- /branches/2780_SAPBA/PreBuildEvent.cmd	(revision 16108)
+++ /branches/2780_SAPBA/PreBuildEvent.cmd	(revision 16108)
@@ -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"
Index: /branches/2780_SAPBA/SAPBA.patch
===================================================================
--- /branches/2780_SAPBA/SAPBA.patch	(revision 16108)
+++ /branches/2780_SAPBA/SAPBA.patch	(revision 16108)
@@ -0,0 +1,1444 @@
+Index: .
+===================================================================
+--- .	(revision 15449)
++++ .	(working copy)
+
+Property changes on: .
+___________________________________________________________________
+Added: svn:global-ignores
+## -0,0 +1 ##
++.vs
+Added: svn:ignore
+## -0,0 +1 ##
++.vs
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+--- .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(revision 15449)
++++ .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(nonexistent)
+
+Property changes on: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+--- .vs/Sliding Window GP/v14/.suo	(revision 15449)
++++ .vs/Sliding Window GP/v14/.suo	(nonexistent)
+
+Property changes on: .vs/Sliding Window GP/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+--- .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(revision 15449)
++++ .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(nonexistent)
+
+Property changes on: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+--- .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(revision 15449)
++++ .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(nonexistent)
+
+Property changes on: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+===================================================================
+--- .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(revision 15449)
++++ .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo	(nonexistent)
+
+Property changes on: .vs/HeuristicLab.Algorithms.SAPBA/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+--- .vs/Sliding Window GP/v14/.suo	(revision 15449)
++++ .vs/Sliding Window GP/v14/.suo	(nonexistent)
+
+Property changes on: .vs/Sliding Window GP/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+--- .vs/Sliding Window GP/v14/.suo	(revision 15449)
++++ .vs/Sliding Window GP/v14/.suo	(nonexistent)
+
+Property changes on: .vs/Sliding Window GP/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+Cannot display: file marked as a binary type.
+svn:mime-type = application/octet-stream
+Index: .vs/Sliding Window GP/v14/.suo
+===================================================================
+--- .vs/Sliding Window GP/v14/.suo	(revision 15449)
++++ .vs/Sliding Window GP/v14/.suo	(nonexistent)
+
+Property changes on: .vs/Sliding Window GP/v14/.suo
+___________________________________________________________________
+Deleted: svn:mime-type
+## -1 +0,0 ##
+-application/octet-stream
+\ No newline at end of property
+Index: HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/HeuristicLab.Algorithms.SAPBA-3.4.csproj	(working copy)
+@@ -30,22 +30,22 @@
+     <WarningLevel>4</WarningLevel>
+   </PropertyGroup>
+   <ItemGroup>
+-    <Reference Include="HeuristicLab.Algorithms.CMAEvolutionStrategy-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+-      <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.CMAEvolutionStrategy-3.4.dll</HintPath>
+-    </Reference>
+     <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+     </Reference>
+-    <Reference Include="HeuristicLab.Algorithms.EvolutionStrategy-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
++    <Reference Include="HeuristicLab.Algorithms.EGO-3.4, Version=3.4.0.0, Culture=neutral, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.EvolutionStrategy-3.3.dll</HintPath>
++      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.EGO-3.4.dll</HintPath>
+     </Reference>
+     <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+     </Reference>
++    <Reference Include="HeuristicLab.Algorithms.OffspringSelectionEvolutionStrategy-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
++      <SpecificVersion>False</SpecificVersion>
++      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Algorithms.OffspringSelectionEvolutionStrategy-3.3.dll</HintPath>
++    </Reference>
+     <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+@@ -58,10 +58,6 @@
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common-3.3.dll</HintPath>
+     </Reference>
+-    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+-      <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+-    </Reference>
+     <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Core-3.3.dll</HintPath>
+@@ -74,7 +70,10 @@
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
+     </Reference>
+-    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec" />
++    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
++      <SpecificVersion>False</SpecificVersion>
++      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Operators-3.3.dll</HintPath>
++    </Reference>
+     <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Optimization-3.3.dll</HintPath>
+@@ -99,18 +98,6 @@
+       <SpecificVersion>False</SpecificVersion>
+       <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+     </Reference>
+-    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+-      <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.DataAnalysis-3.3.dll</HintPath>
+-    </Reference>
+-    <Reference Include="HeuristicLab.Problems.Instances.DataAnalysis.Views-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+-      <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Problems.Instances.DataAnalysis.Views-3.3.dll</HintPath>
+-    </Reference>
+-    <Reference Include="HeuristicLab.Random-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+-      <SpecificVersion>False</SpecificVersion>
+-      <HintPath>..\..\..\trunk\sources\bin\HeuristicLab.Random-3.3.dll</HintPath>
+-    </Reference>
+     <Reference Include="System" />
+     <Reference Include="System.Core" />
+     <Reference Include="System.Windows.Forms" />
+@@ -122,9 +109,10 @@
+     <Reference Include="System.Xml" />
+   </ItemGroup>
+   <ItemGroup>
+-    <Compile Include="EgoUtilities.cs" />
+-    <Compile Include="Strategies\IndividualStrategy.cs" />
+-    <Compile Include="Strategies\GenerationalStrategy.cs" />
++    <Compile Include="Operators\FixedSolutionCreator.cs" />
++    <Compile Include="SapbaUtilities.cs" />
++    <Compile Include="Strategies\LamarckianStrategy.cs" />
++    <Compile Include="Strategies\InfillStrategy.cs" />
+     <Compile Include="SurrogateAssistedPopulationBasedAlgorithm.cs" />
+     <Compile Include="Interfaces\ISurrogateStrategy.cs" />
+     <Compile Include="Interfaces\ISurrogateAlgorithm.cs" />
+Index: HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Interfaces/ISurrogateStrategy.cs	(working copy)
+@@ -19,7 +19,6 @@
+  */
+ #endregion
+ 
+-using System.Threading;
+ using HeuristicLab.Core;
+ using HeuristicLab.Encodings.RealVectorEncoding;
+ using HeuristicLab.Optimization;
+@@ -29,6 +28,6 @@
+     double Evaluate(RealVector r, IRandom random);
+     void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random);
+     void Initialize(SurrogateAssistedPopulationBasedAlgorithm algorithm);
+-    void UpdateCancellation(CancellationToken cancellationToken);
++    bool Maximization();
+   }
+ }
+Index: HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(nonexistent)
++++ HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(working copy)
+@@ -0,0 +1,30 @@
++ï»¿using HeuristicLab.Common;
++using HeuristicLab.Core;
++using HeuristicLab.Data;
++using HeuristicLab.Encodings.RealVectorEncoding;
++using HeuristicLab.Optimization;
++using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
++
++namespace HeuristicLab.Algorithms.SAPBA.Operators {
++  [Item("FixedRealVectorCreator", "An operator which creates a new real vector cloned from a single Point")]
++  [StorableClass]
++  public class FixedRealVectorCreator : RealVectorCreator, IStrategyParameterCreator {
++    [Storable]
++    private RealVector Point;
++
++    [StorableConstructor]
++    protected FixedRealVectorCreator(bool deserializing) : base(deserializing) { }
++    protected FixedRealVectorCreator(FixedRealVectorCreator original, Cloner cloner) : base(original, cloner) {
++      Point = cloner.Clone(original.Point);
++    }
++    public FixedRealVectorCreator(RealVector r) : base() {
++      Point = r;
++    }
++    public override IDeepCloneable Clone(Cloner cloner) { return new FixedRealVectorCreator(this, cloner); }
++    protected override RealVector Create(IRandom random, IntValue length, DoubleMatrix bounds) {
++      return (RealVector)Point.Clone();
++    }
++  }
++
++}
++
+Index: HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(nonexistent)
++++ HeuristicLab.Algorithms.SAPBA/Operators/FixedSolutionCreator.cs	(working copy)
+@@ -0,0 +1,30 @@
++ï»¿using HeuristicLab.Common;
++using HeuristicLab.Core;
++using HeuristicLab.Data;
++using HeuristicLab.Encodings.RealVectorEncoding;
++using HeuristicLab.Optimization;
++using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
++
++namespace HeuristicLab.Algorithms.SAPBA.Operators {
++  [Item("FixedRealVectorCreator", "An operator which creates a new real vector cloned from a single Point")]
++  [StorableClass]
++  public class FixedRealVectorCreator : RealVectorCreator, IStrategyParameterCreator {
++    [Storable]
++    private RealVector Point;
++
++    [StorableConstructor]
++    protected FixedRealVectorCreator(bool deserializing) : base(deserializing) { }
++    protected FixedRealVectorCreator(FixedRealVectorCreator original, Cloner cloner) : base(original, cloner) {
++      Point = cloner.Clone(original.Point);
++    }
++    public FixedRealVectorCreator(RealVector r) : base() {
++      Point = r;
++    }
++    public override IDeepCloneable Clone(Cloner cloner) { return new FixedRealVectorCreator(this, cloner); }
++    protected override RealVector Create(IRandom random, IntValue length, DoubleMatrix bounds) {
++      return (RealVector)Point.Clone();
++    }
++  }
++
++}
++
+Index: HeuristicLab.Algorithms.SAPBA/Plugin.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Plugin.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Plugin.cs	(working copy)
+@@ -25,25 +25,22 @@
+ using HeuristicLab.PluginInfrastructure;
+ 
+ namespace HeuristicLab.Algorithms.SAPBA {
+-  [Plugin("HeuristicLab.Algorithms.SAPBA", "3.4.5.14893")]
++  [Plugin("HeuristicLab.Algorithms.SAPBA", "3.4.5.14894")]
+   [PluginFile("HeuristicLab.Algorithms.SAPBA-3.4.dll", PluginFileType.Assembly)]
+-  [PluginFile("displayModelFrame.html", PluginFileType.Data)]
+-  [PluginDependency("HeuristicLab.Algorithms.CMAEvolutionStrategy", "3.4")]
+   [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
++  [PluginDependency("HeuristicLab.Algorithms.EGO", "3.4")]
++  [PluginDependency("HeuristicLab.Algorithms.GeneticAlgorithm", "3.3")]
++  [PluginDependency("HeuristicLab.Algorithms.OffspringSelectionEvolutionStrategy", "3.3")]
+   [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.Data", "3.3")]
+   [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+-  [PluginDependency("HeuristicLab.Operators","3.3")]
+   [PluginDependency("HeuristicLab.Optimization","3.3")]
+   [PluginDependency("HeuristicLab.Parameters","3.3")]
+   [PluginDependency("HeuristicLab.Persistence","3.3")]
+   [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+-  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+-  [PluginDependency("HeuristicLab.Random", "3.3")]
+   public class HeuristicLabProblemsDataAnalysisSymbolicViewsPlugin : PluginBase {
+   }
+ }
+Index: HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Plugin.cs.frame	(working copy)
+@@ -27,23 +27,20 @@
+ namespace HeuristicLab.Algorithms.SAPBA {
+   [Plugin("HeuristicLab.Algorithms.SAPBA", "3.4.5.$WCREV$")]
+   [PluginFile("HeuristicLab.Algorithms.SAPBA-3.4.dll", PluginFileType.Assembly)]
+-  [PluginFile("displayModelFrame.html", PluginFileType.Data)]
+-  [PluginDependency("HeuristicLab.Algorithms.CMAEvolutionStrategy", "3.4")]
+   [PluginDependency("HeuristicLab.Algorithms.DataAnalysis", "3.4")]
++  [PluginDependency("HeuristicLab.Algorithms.EGO", "3.4")]
++  [PluginDependency("HeuristicLab.Algorithms.GeneticAlgorithm", "3.3")]
++  [PluginDependency("HeuristicLab.Algorithms.OffspringSelectionEvolutionStrategy", "3.3")]
+   [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.Data", "3.3")]
+   [PluginDependency("HeuristicLab.Encodings.RealVectorEncoding", "3.3")]
+-  [PluginDependency("HeuristicLab.Operators","3.3")]
+   [PluginDependency("HeuristicLab.Optimization","3.3")]
+   [PluginDependency("HeuristicLab.Parameters","3.3")]
+   [PluginDependency("HeuristicLab.Persistence","3.3")]
+   [PluginDependency("HeuristicLab.Problems.DataAnalysis", "3.4")]
+-  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
+-  [PluginDependency("HeuristicLab.Random", "3.3")]
+   public class HeuristicLabProblemsDataAnalysisSymbolicViewsPlugin : PluginBase {
+   }
+ }
+Index: HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Problems/SurrogateProblem.cs	(working copy)
+@@ -1,5 +1,29 @@
+-ï»¿using HeuristicLab.Common;
++ï»¿#region License Information
++/* HeuristicLab
++ * Copyright (C) 2002-2016 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;
+ using HeuristicLab.Core;
++using HeuristicLab.Data;
+ using HeuristicLab.Encodings.RealVectorEncoding;
+ using HeuristicLab.Optimization;
+ using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+@@ -6,9 +30,9 @@
+ 
+ namespace HeuristicLab.Algorithms.SAPBA {
+   [StorableClass]
+-  [Item("Surrogate problem (single-objective)", "Wrapper for a problem that allows surrogate models to mitigate some of the work")]
++  [Item("Surrogate problem (single-objective)", "A problem that uses a Surrogate Strategy to emulate an expensive problem")]
+   public class SurrogateProblem : SingleObjectiveBasicProblem<RealVectorEncoding> {
+-
++    public override bool Maximization => Strategy?.Maximization() ?? false;
+     [Storable]
+     private ISurrogateStrategy Strategy;
+ 
+@@ -18,11 +42,12 @@
+     [StorableHook(HookType.AfterDeserialization)]
+     private void AfterDeserialization() { }
+     protected SurrogateProblem(SurrogateProblem original, Cloner cloner) : base(original, cloner) {
+-      Strategy = original?.Strategy;
++      Strategy = cloner.Clone(original.Strategy);
+     }
+-    public override IDeepCloneable Clone(Cloner cloner) { return new SurrogateProblem(this, cloner); }
+-    public SurrogateProblem() {
++    public override IDeepCloneable Clone(Cloner cloner) {
++      return new SurrogateProblem(this, cloner);
+     }
++    public SurrogateProblem() { }
+     #endregion
+ 
+     public override double Evaluate(Individual individual, IRandom random) {
+@@ -32,15 +57,32 @@
+       base.Analyze(individuals, qualities, results, random);
+       Strategy.Analyze(individuals, qualities, results, random);
+     }
++    public override IEnumerable<Individual> GetNeighbors(Individual individual, IRandom random) {
++      var bounds = Encoding.Bounds;
++      var michalewiczIteration = 0;
++      while (true) {
++        var neighbour = individual.Copy();
++        var r = neighbour.RealVector();
++        switch (random.Next(5)) {
++          case 0: UniformOnePositionManipulator.Apply(random, r, bounds); break;
++          case 1: FixedNormalAllPositionsManipulator.Apply(random, r, new RealVector(new[] { 0.1 })); break;
++          case 2: MichalewiczNonUniformAllPositionsManipulator.Apply(random, r, bounds, new IntValue(michalewiczIteration++), new IntValue(10000), new DoubleValue(5.0)); break;
++          case 3: MichalewiczNonUniformOnePositionManipulator.Apply(random, r, bounds, new IntValue(michalewiczIteration++), new IntValue(10000), new DoubleValue(5.0)); break;
++          case 4: BreederGeneticAlgorithmManipulator.Apply(random, r, bounds, new DoubleValue(0.1)); break;
++          default: throw new NotImplementedException();
++        }
++        yield return neighbour;
++        michalewiczIteration %= 10000;
++      }
++    }
+ 
+-    public override bool Maximization { get; }
+-
+-    public void SetStrategy(ISurrogateStrategy strategy) {
++    public void Initialize(SingleObjectiveBasicProblem<IEncoding> expensiveProblem, ISurrogateStrategy strategy) {
++      if (expensiveProblem == null) return;
++      var enc = (RealVectorEncoding)expensiveProblem.Encoding;
++      Encoding.Bounds = enc.Bounds;
++      Encoding.Length = enc.Length;
++      SolutionCreator = expensiveProblem.SolutionCreator;
+       Strategy = strategy;
+     }
+-    public void SetProblem(SingleObjectiveBasicProblem<IEncoding> expensiveProblem) {
+-      if (expensiveProblem != null) Encoding = expensiveProblem.Encoding as RealVectorEncoding;
+-    }
+-
+   }
+ }
+\ No newline at end of file
+Index: HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Properties/AssemblyInfo.cs	(working copy)
+@@ -52,4 +52,4 @@
+ // You can specify all the values or you can default the Build and Revision Numbers 
+ // by using the '*' as shown below:
+ [assembly: AssemblyVersion("3.4.0.0")]
+-[assembly: AssemblyFileVersion("3.4.0.14893")]
++[assembly: AssemblyFileVersion("3.4.0.14894")]
+Index: HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs	(nonexistent)
++++ HeuristicLab.Algorithms.SAPBA/SapbaUtilities.cs	(working copy)
+@@ -0,0 +1,168 @@
++ï»¿#region License Information
++/* HeuristicLab
++ * Copyright (C) 2002-2016 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.Threading;
++using HeuristicLab.Algorithms.DataAnalysis;
++using HeuristicLab.Common;
++using HeuristicLab.Core;
++using HeuristicLab.Data;
++using HeuristicLab.Encodings.RealVectorEncoding;
++using HeuristicLab.Optimization;
++using HeuristicLab.Problems.DataAnalysis;
++
++namespace HeuristicLab.Algorithms.SAPBA {
++  internal static class SapbaUtilities {
++    //Extention methods for convenience
++    public static int ArgMax<T>(this IEnumerable<T> values, Func<T, double> func) {
++      var max = double.MinValue;
++      var maxIdx = 0;
++      var idx = 0;
++      foreach (var v in values) {
++        var d = func.Invoke(v);
++        if (d > max) {
++          max = d;
++          maxIdx = idx;
++        }
++        idx++;
++      }
++      return maxIdx;
++    }
++    public static int ArgMin<T>(this IEnumerable<T> values, Func<T, double> func) {
++      return ArgMax(values, x => -func.Invoke(x));
++    }
++    public static double GetEstimation(this IRegressionModel model, RealVector r) {
++      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
++      return model.GetEstimatedValues(dataset, new[] { 0 }).First();
++    }
++    public static double GetVariance(this IConfidenceRegressionModel model, RealVector r) {
++      var dataset = GetDataSet(new[] { new Tuple<RealVector, double>(r, 0.0) }, false);
++      return model.GetEstimatedVariances(dataset, new[] { 0 }).First();
++    }
++    public static double GetDoubleValue(this IDataset dataset, int i, int j) {
++      return dataset.GetDoubleValue("input" + j, i);
++    }
++
++    //Sub-Algorithms
++    public static ResultCollection SyncRunSubAlgorithm(IAlgorithm alg, int random) {
++      if (alg.Parameters.ContainsKey("SetSeedRandomly") && alg.Parameters.ContainsKey("Seed")) {
++        var setSeed = alg.Parameters["SetSeedRandomly"].ActualValue as BoolValue;
++        var seed = alg.Parameters["Seed"].ActualValue as IntValue;
++        if (seed == null || setSeed == null) throw new ArgumentException("wrong SeedParametertypes");
++        setSeed.Value = false;
++        seed.Value = random;
++
++      }
++      EventWaitHandle trigger = new AutoResetEvent(false);
++      Exception ex = null;
++      EventHandler<EventArgs<Exception>> exhandler = (sender, e) => ex = e.Value;
++      EventHandler stoppedHandler = (sender, e) => trigger.Set();
++      alg.ExceptionOccurred += exhandler;
++      alg.Stopped += stoppedHandler;
++      alg.Prepare();
++      alg.Start();
++      trigger.WaitOne();
++      alg.ExceptionOccurred -= exhandler;
++      alg.Stopped -= stoppedHandler;
++      if (ex != null) throw ex;
++      return alg.Results;
++    }
++    public static IRegressionSolution BuildModel(IReadOnlyList<Tuple<RealVector, double>> samples, IDataAnalysisAlgorithm<IRegressionProblem> regressionAlgorithm, IRandom random, bool removeDuplicates = true, IRegressionSolution oldSolution = null) {
++      var dataset = GetDataSet(samples, removeDuplicates);
++      var problemdata = new RegressionProblemData(dataset, dataset.VariableNames.Where(x => !x.Equals("output")), "output");
++      problemdata.TrainingPartition.Start = 0;
++      problemdata.TrainingPartition.End = dataset.Rows;
++      problemdata.TestPartition.Start = dataset.Rows;
++      problemdata.TestPartition.End = dataset.Rows;
++
++      if (regressionAlgorithm.Problem == null) regressionAlgorithm.Problem = new RegressionProblem();
++      var problem = regressionAlgorithm.Problem;
++      problem.ProblemDataParameter.Value = problemdata;
++      var i = 0;
++      IRegressionSolution solution = null;
++
++      while (solution == null && i++ < 100) {
++        var results = SyncRunSubAlgorithm(regressionAlgorithm, random.Next(int.MaxValue));
++        solution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
++      }
++
++      //special treatement for GaussianProcessRegression
++      var gp = regressionAlgorithm as GaussianProcessRegression;
++      var oldGaussian = oldSolution as GaussianProcessRegressionSolution;
++      if (gp != null && oldGaussian != null) {
++        const double noise = 0.0;
++        var n = samples.First().Item1.Length;
++        var mean = (IMeanFunction)oldGaussian.Model.MeanFunction.Clone();
++        var cov = (ICovarianceFunction)oldGaussian.Model.CovarianceFunction.Clone();
++        if (mean.GetNumberOfParameters(n) != 0 || cov.GetNumberOfParameters(n) != 0) throw new ArgumentException("DEBUG: assumption about fixed paramters wrong");
++        double[] hyp = { noise };
++        try {
++          var model = new GaussianProcessModel(problemdata.Dataset, problemdata.TargetVariable, problemdata.AllowedInputVariables, problemdata.TrainingIndices, hyp, mean, cov);
++          model.FixParameters();
++          var sol = new GaussianProcessRegressionSolution(model, problemdata);
++          if (solution == null || solution.TrainingMeanSquaredError > sol.TrainingMeanSquaredError) solution = sol;
++        }
++        catch (ArgumentException) { }
++      }
++      if (solution == null) throw new ArgumentException("The algorithm didn't return a model");
++      regressionAlgorithm.Runs.Clear();
++      return solution;
++    }
++
++    //RegressionModel extensions
++    public const double DuplicateResolution = 0.000001;
++    public static Dataset GetDataSet(IReadOnlyList<Tuple<RealVector, double>> samples, bool removeDuplicates) {
++      if (removeDuplicates) samples = RemoveDuplicates(samples); //TODO duplicate removal leads to incorrect uncertainty values in models
++      var dimensions = samples[0].Item1.Length + 1;
++      var data = new double[samples.Count, dimensions];
++      var names = new string[dimensions - 1];
++      for (var i = 0; i < names.Length; i++) names[i] = "input" + i;
++      for (var j = 0; j < samples.Count; j++) {
++        for (var i = 0; i < names.Length; i++) data[j, i] = samples[j].Item1[i];
++        data[j, dimensions - 1] = samples[j].Item2;
++      }
++      return new Dataset(names.Concat(new[] { "output" }).ToArray(), data);
++    }
++    private static IReadOnlyList<Tuple<RealVector, double>> RemoveDuplicates(IReadOnlyList<Tuple<RealVector, double>> samples) {
++      var res = new List<Tuple<RealVector, double, int>>();
++      foreach (var sample in samples) {
++        if (res.Count == 0) {
++          res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
++          continue;
++        }
++        var index = res.ArgMin(x => Euclidian(sample.Item1, x.Item1));
++        var d = Euclidian(res[index].Item1, sample.Item1);
++        if (d > DuplicateResolution) res.Add(new Tuple<RealVector, double, int>(sample.Item1, sample.Item2, 1));
++        else {
++          var t = res[index];
++          res.RemoveAt(index);
++          res.Add(new Tuple<RealVector, double, int>(t.Item1, t.Item2 + sample.Item2, t.Item3 + 1));
++        }
++      }
++      return res.Select(x => new Tuple<RealVector, double>(x.Item1, x.Item2 / x.Item3)).ToArray();
++    }
++    private static double Euclidian(IEnumerable<double> a, IEnumerable<double> b) {
++      return Math.Sqrt(a.Zip(b, (d, d1) => d - d1).Sum(d => d * d));
++    }
++  }
++}
+Index: HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs	(nonexistent)
++++ HeuristicLab.Algorithms.SAPBA/Strategies/InfillStrategy.cs	(working copy)
+@@ -0,0 +1,113 @@
++ï»¿#region License Information
++/* HeuristicLab
++ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
++ *
++ * This file is part of HeuristicLab.
++ *
++ * HeuristicLab is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * HeuristicLab is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
++ */
++#endregion
++
++using System;
++using System.Linq;
++using HeuristicLab.Algorithms.EGO;
++using HeuristicLab.Common;
++using HeuristicLab.Core;
++using HeuristicLab.Data;
++using HeuristicLab.Encodings.RealVectorEncoding;
++using HeuristicLab.Optimization;
++using HeuristicLab.Parameters;
++using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
++
++namespace HeuristicLab.Algorithms.SAPBA {
++  [StorableClass]
++  public class InfillStrategy : StrategyBase {
++    #region Parameternames
++    public const string NoGenerationsParameterName = "Number of generations";
++    public const string NoIndividualsParameterName = "Number of individuals";
++    public const string InfillCriterionParameterName = "InfillCriterion";
++    #endregion
++    #region Paramterproperties
++    public IFixedValueParameter<IntValue> NoGenerationsParameter => Parameters[NoGenerationsParameterName] as IFixedValueParameter<IntValue>;
++    public IFixedValueParameter<IntValue> NoIndividualsParameter => Parameters[NoIndividualsParameterName] as IFixedValueParameter<IntValue>;
++    public IConstrainedValueParameter<IInfillCriterion> InfillCriterionParameter => Parameters[InfillCriterionParameterName] as IConstrainedValueParameter<IInfillCriterion>;
++    #endregion
++    #region Properties
++    public IntValue NoGenerations => NoGenerationsParameter.Value;
++    public IntValue NoIndividuals => NoIndividualsParameter.Value;
++    public IInfillCriterion InfillCriterion => InfillCriterionParameter.Value;
++    [Storable]
++    public int Generations;
++    #endregion
++
++    #region Constructors
++    [StorableConstructor]
++    protected InfillStrategy(bool deserializing) : base(deserializing) { }
++    [StorableHook(HookType.AfterDeserialization)]
++    private void AfterDeserialization() {
++      AttachListeners();
++    }
++    protected InfillStrategy(InfillStrategy original, Cloner cloner) : base(original, cloner) {
++      Generations = original.Generations;
++      AttachListeners();
++    }
++    public InfillStrategy() {
++      var critera = new ItemSet<IInfillCriterion> { new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuality(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
++      Parameters.Add(new FixedValueParameter<IntValue>(NoGenerationsParameterName, "The number of generations before a new model is constructed", new IntValue(3)));
++      Parameters.Add(new FixedValueParameter<IntValue>(NoIndividualsParameterName, "The number of individuals that are sampled each generation ", new IntValue(3)));
++      Parameters.Add(new ConstrainedValueParameter<IInfillCriterion>(InfillCriterionParameterName, "The infill criterion used to cheaply evaluate points.", critera, critera.First()));
++      AttachListeners();
++    }
++    public override IDeepCloneable Clone(Cloner cloner) {
++      return new InfillStrategy(this, cloner);
++    }
++    #endregion
++
++    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) { }
++    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
++      if (RegressionSolution != null && Generations < NoGenerations.Value) Generations++;
++      else {
++        //Select NoIndividuals best samples
++        var samples = individuals
++          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
++          .OrderBy(t => Problem.Maximization ? -t.Item2 : t.Item2)
++          .Take(NoIndividuals.Value)
++          .Select(t => t.Item1.RealVector());
++        foreach (var indi in samples) EvaluateSample(indi, random);
++        BuildRegressionSolution(random);
++        Generations = 0;
++      }
++    }
++    protected override void Initialize() {
++      Generations = 0;
++    }
++
++    #region events
++    private void AttachListeners() {
++      ModelChanged += OnModelChanged;
++    }
++    private void OnModelChanged(object sender, EventArgs e) {
++      InfillCriterion.Encoding = Problem?.Encoding as RealVectorEncoding;
++      InfillCriterion.RegressionSolution = RegressionSolution;
++      InfillCriterion.ExpensiveMaximization = Problem?.Maximization ?? false;
++      if (RegressionSolution != null && InfillCriterion.Encoding != null)
++        InfillCriterion.Initialize();
++    }
++    #endregion
++
++    protected override double Estimate(RealVector point, IRandom random) {
++      return InfillCriterion.Maximization() != Maximization() ? -InfillCriterion.Evaluate(point) : InfillCriterion.Evaluate(point);
++    }
++  }
++}
+Index: HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs	(nonexistent)
++++ HeuristicLab.Algorithms.SAPBA/Strategies/LamarckianStrategy.cs	(working copy)
+@@ -0,0 +1,249 @@
++ï»¿#region License Information
++/* HeuristicLab
++ * Copyright (C) 2002-2016 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.Algorithms.DataAnalysis;
++using HeuristicLab.Algorithms.EGO;
++using HeuristicLab.Algorithms.SAPBA.Operators;
++using HeuristicLab.Analysis;
++using HeuristicLab.Common;
++using HeuristicLab.Core;
++using HeuristicLab.Data;
++using HeuristicLab.Encodings.RealVectorEncoding;
++using HeuristicLab.Optimization;
++using HeuristicLab.Parameters;
++using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
++using HeuristicLab.Problems.DataAnalysis;
++
++namespace HeuristicLab.Algorithms.SAPBA {
++  [StorableClass]
++  public class LamarckianStrategy : InfillStrategy {
++    #region Parameternames
++    public const string NoTrainingPointsParameterName = "Number of Trainingpoints";
++    public const string LocalInfillCriterionParameterName = "LocalInfillCriterion";
++    public const string OptimizationAlgorithmParameterName = "Optimization Algorithm";
++    public const string RegressionAlgorithmParameterName = "Regression Algorithm";
++    #endregion
++    #region Parameters
++    public IFixedValueParameter<IntValue> NoTrainingPointsParameter => Parameters[NoTrainingPointsParameterName] as IFixedValueParameter<IntValue>;
++    public IValueParameter<IAlgorithm> OptimizationAlgorithmParameter => Parameters[OptimizationAlgorithmParameterName] as IValueParameter<IAlgorithm>;
++    public IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>> RegressionAlgorithmParameter => Parameters[RegressionAlgorithmParameterName] as IValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>;
++    public IConstrainedValueParameter<IInfillCriterion> LocalInfillCriterionParameter => Parameters[LocalInfillCriterionParameterName] as IConstrainedValueParameter<IInfillCriterion>;
++    #endregion
++    #region Properties
++    public IntValue NoTrainingPoints => NoTrainingPointsParameter.Value;
++    public IAlgorithm OptimizationAlgorithm => OptimizationAlgorithmParameter.Value;
++    public IDataAnalysisAlgorithm<IRegressionProblem> RegressionAlgorithm => RegressionAlgorithmParameter.Value;
++    public IInfillCriterion LocalInfillCriterion => LocalInfillCriterionParameter.Value;
++    #endregion
++
++    #region Constructors
++    [StorableConstructor]
++    protected LamarckianStrategy(bool deserializing) : base(deserializing) { }
++    [StorableHook(HookType.AfterDeserialization)]
++    private void AfterDeserialization() {
++      RegisterParameterEvents();
++    }
++    protected LamarckianStrategy(LamarckianStrategy original, Cloner cloner) : base(original, cloner) {
++      RegisterParameterEvents();
++    }
++    public LamarckianStrategy() {
++      var localCritera = new ItemSet<IInfillCriterion> { new ExpectedQuality(), new ExpectedImprovement(), new AugmentedExpectedImprovement(), new ExpectedQuantileImprovement(), new MinimalQuantileCriterium(), new PluginExpectedImprovement() };
++      var osEs = new OffspringSelectionEvolutionStrategy.OffspringSelectionEvolutionStrategy {
++        Problem = new InfillProblem(),
++        ComparisonFactor = { Value = 1.0 },
++        MaximumGenerations = { Value = 1000 },
++        MaximumEvaluatedSolutions = { Value = 100000 },
++        PlusSelection = { Value = true },
++        PopulationSize = { Value = 1 }
++      };
++      osEs.MutatorParameter.Value = osEs.MutatorParameter.ValidValues.OfType<MultiRealVectorManipulator>().First();
++      Parameters.Add(new FixedValueParameter<IntValue>(NoTrainingPointsParameterName, "The number of sample points used to create a local model", new IntValue(50)));
++      Parameters.Add(new ConstrainedValueParameter<IInfillCriterion>(LocalInfillCriterionParameterName, "The infill criterion used to cheaply evaluate points.", localCritera, localCritera.First()));
++      Parameters.Add(new ValueParameter<IAlgorithm>(OptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", osEs));
++      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", new GaussianProcessRegression { Problem = new RegressionProblem() }));
++      RegisterParameterEvents();
++    }
++    public override IDeepCloneable Clone(Cloner cloner) {
++      return new LamarckianStrategy(this, cloner);
++    }
++    #endregion
++
++    //Short lived stores for analysis
++    private readonly List<double> LamarckValues = new List<double>();
++    private readonly List<double> SampleValues = new List<double>();
++
++    protected override void Initialize() {
++      base.Initialize();
++      var infillProblem = OptimizationAlgorithm.Problem as InfillProblem;
++      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm does not have an InfillProblem.");
++      infillProblem.InfillCriterion = LocalInfillCriterion;
++    }
++    protected override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random) {
++      base.Analyze(individuals, qualities, results, globalResults, random);
++      const string plotName = "Lamarck Comparison";
++      const string lamarckRow = "Lamarck Values";
++      const string samplesRow = "Original Values";
++      if (!globalResults.ContainsKey(plotName))
++        globalResults.Add(new Result(plotName, new DataTable(plotName)));
++
++      var plot = (DataTable)globalResults[plotName].Value;
++      if (!plot.Rows.ContainsKey(lamarckRow)) plot.Rows.Add(new DataRow(lamarckRow));
++      if (!plot.Rows.ContainsKey(samplesRow)) plot.Rows.Add(new DataRow(samplesRow));
++      plot.Rows[lamarckRow].Values.AddRange(LamarckValues);
++      plot.Rows[samplesRow].Values.AddRange(SampleValues);
++      LamarckValues.Clear();
++      SampleValues.Clear();
++
++      //analyze Hypervolumes 
++      const string volPlotName = "Hypervolumes Comparison";
++      const string mainRowName = "Population Volume (log)";
++      const string subspaceRowName = "Subspace Volume (log) for Lamarck Candidate ";
++      if (!globalResults.ContainsKey(volPlotName))
++        globalResults.Add(new Result(volPlotName, new DataTable(volPlotName)));
++
++      plot = (DataTable)globalResults[volPlotName].Value;
++      if (!plot.Rows.ContainsKey(mainRowName)) plot.Rows.Add(new DataRow(mainRowName));
++      var v = Math.Log(GetStableVolume(GetBoundingBox(individuals.Select(x => x.RealVector()))));
++      plot.Rows[mainRowName].Values.Add(v);
++
++      var indis = individuals
++          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
++          .OrderBy(t => SapbaAlgorithm.Problem.Maximization ? -t.Item2 : t.Item2)
++          .Take(NoIndividuals.Value)
++          .Select(t => t.Item1).ToArray();
++
++      for (var i = 0; i < indis.Length; i++) {
++        var samples = GetNearestSamples(NoTrainingPoints.Value, indis[i].RealVector());
++        var d = Math.Log(GetStableVolume(GetBoundingBox(samples.Select(x => x.Item1))));
++        if (!plot.Rows.ContainsKey(subspaceRowName + i)) plot.Rows.Add(new DataRow(subspaceRowName + i));
++        plot.Rows[subspaceRowName + i].Values.Add(d);
++      }
++
++
++
++    }
++    protected override void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random) {
++      if (RegressionSolution == null) return;
++      if (Generations < NoGenerations.Value) Generations++;
++      else {
++        //Select best Individuals
++        var indis = individuals
++          .Zip(qualities, (individual, d) => new Tuple<Individual, double>(individual, d))
++          .OrderBy(t => Problem.Maximization ? -t.Item2 : t.Item2)
++          .Take(NoIndividuals.Value)
++          .Select(t => t.Item1).ToArray();
++        //Evaluate individuals
++        foreach (var individual in indis)
++          SampleValues.Add(EvaluateSample(individual.RealVector(), random).Item2);
++
++        //Perform memetic replacement for all points
++        for (var i = 0; i < indis.Length; i++) {
++          var vector = indis[i].RealVector();
++          var altVector = OptimizeInfillProblem(vector, random);
++          LamarckValues.Add(EvaluateSample(altVector, random).Item2);
++          if (LamarckValues[i] < SampleValues[i] == Problem.Maximization) continue;
++          for (var j = 0; j < vector.Length; j++) vector[j] = altVector[j];
++        }
++
++        BuildRegressionSolution(random);
++        Generations = 0;
++      }
++    }
++
++    #region Events
++    private void RegisterParameterEvents() {
++      OptimizationAlgorithmParameter.ValueChanged += OnInfillAlgorithmChanged;
++      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
++      LocalInfillCriterionParameter.ValueChanged += OnInfillCriterionChanged;
++    }
++    private void OnInfillCriterionChanged(object sender, EventArgs e) {
++      ((InfillProblem)OptimizationAlgorithm.Problem).InfillCriterion = LocalInfillCriterion;
++    }
++    private void OnInfillAlgorithmChanged(object sender, EventArgs e) {
++      OptimizationAlgorithm.Problem = new InfillProblem { InfillCriterion = LocalInfillCriterion };
++      OptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged; //avoid double attaching
++      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
++    }
++    private void OnInfillProblemChanged(object sender, EventArgs e) {
++      OptimizationAlgorithm.ProblemChanged -= OnInfillProblemChanged;
++      OptimizationAlgorithm.Problem = new InfillProblem { InfillCriterion = LocalInfillCriterion };
++      OptimizationAlgorithm.ProblemChanged += OnInfillProblemChanged;
++    }
++    #endregion
++
++    #region helpers
++    private RealVector OptimizeInfillProblem(RealVector point, IRandom random) {
++      var infillProblem = OptimizationAlgorithm.Problem as InfillProblem;
++      if (infillProblem == null) throw new ArgumentException("InfillOptimizationAlgorithm does not have an InfillProblem.");
++      if (infillProblem.InfillCriterion != LocalInfillCriterion) throw new ArgumentException("InfillCiriterion for Problem is not correctly set.");
++
++      var points = Math.Min(NoTrainingPoints.Value, Samples.Count);
++      var samples = GetNearestSamples(points, point);
++      var regression = SapbaUtilities.BuildModel(samples, RegressionAlgorithm, random);
++      var box = GetBoundingBox(samples.Select(x => x.Item1));
++
++      infillProblem.Encoding.Length = ((RealVectorEncoding)Problem.Encoding).Length;
++      infillProblem.Encoding.Bounds = box;
++      infillProblem.Encoding.SolutionCreator = new FixedRealVectorCreator(point);
++      infillProblem.Initialize(regression, Problem.Maximization);
++      var res = SapbaUtilities.SyncRunSubAlgorithm(OptimizationAlgorithm, random.Next(int.MaxValue));
++      if (!res.ContainsKey(InfillProblem.BestInfillSolutionResultName)) throw new ArgumentException("The InfillOptimizationAlgorithm did not return a best solution");
++      var v = res[InfillProblem.BestInfillSolutionResultName].Value as RealVector;
++      if (v == null) throw new ArgumentException("The InfillOptimizationAlgorithm did not return the expected result types");
++      if (!InBounds(v, box)) throw new ArgumentException("Vector not in bounds");
++      OptimizationAlgorithm.Runs.Clear();
++      return v;
++    }
++    private Tuple<RealVector, double>[] GetNearestSamples(int noSamples, RealVector point) {
++      return Samples.Select(sample => Tuple.Create(SquaredEuclidean(sample.Item1, point), sample)).OrderBy(x => x.Item1).Take(noSamples).Select(x => x.Item2).ToArray();
++    }
++    private static DoubleMatrix GetBoundingBox(IEnumerable<RealVector> samples) {
++      DoubleMatrix m = null;
++      foreach (var sample in samples)
++        if (m == null) {
++          m = new DoubleMatrix(sample.Length, 2);
++          for (var i = 0; i < sample.Length; i++) m[i, 0] = m[i, 1] = sample[i];
++        } else
++          for (var i = 0; i < sample.Length; i++) {
++            m[i, 0] = Math.Min(m[i, 0], sample[i]);
++            m[i, 1] = Math.Max(m[i, 1], sample[i]);
++          }
++      return m;
++    }
++
++    //the volume of a bounded-box whith slightly increased dimensions (Volume can never reach 0)
++    private static double GetStableVolume(DoubleMatrix bounds) {
++      var res = 1.0;
++      for (var i = 0; i < bounds.Rows; i++) res *= bounds[i, 1] - bounds[i, 0] + 0.1;
++      return res;
++    }
++    private static bool InBounds(RealVector r, DoubleMatrix bounds) {
++      return !r.Where((t, i) => t < bounds[i, 0] || t > bounds[i, 1]).Any();
++    }
++    private static double SquaredEuclidean(RealVector a, RealVector b) {
++      return a.Select((t, i) => t - b[i]).Sum(d => d * d);
++    }
++    #endregion
++  }
++}
+Index: HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/Strategies/StrategyBase.cs	(working copy)
+@@ -22,7 +22,6 @@
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+-using System.Threading;
+ using HeuristicLab.Analysis;
+ using HeuristicLab.Common;
+ using HeuristicLab.Core;
+@@ -32,20 +31,39 @@
+ using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+ using HeuristicLab.Problems.DataAnalysis;
+ 
+-namespace HeuristicLab.Algorithms.SAPBA.Strategies {
++namespace HeuristicLab.Algorithms.SAPBA {
+   [StorableClass]
+   public abstract class StrategyBase : ParameterizedNamedItem, ISurrogateStrategy {
+     #region Properties
+     [Storable]
+-    protected SurrogateAssistedPopulationBasedAlgorithm Algorithm;
++    protected SurrogateAssistedPopulationBasedAlgorithm SapbaAlgorithm;
++    protected SingleObjectiveBasicProblem<IEncoding> Problem => SapbaAlgorithm?.Problem;
+     [Storable]
+-    private List<Tuple<RealVector, double>> Samples;
++    protected List<Tuple<RealVector, double>> Samples;
+     [Storable]
+-    protected IRegressionSolution RegressionSolution;
+-    protected CancellationToken Cancellation;
+-    private IEnumerable<Tuple<RealVector, double>> TruncatedSamples => Samples.Count > Algorithm.MaximalDatasetSize && Algorithm.MaximalDatasetSize > 0 ? Samples.Skip(Samples.Count - Algorithm.MaximalDatasetSize) : Samples;
++    private IRegressionSolution regressionSolution;
++
++    public IRegressionSolution RegressionSolution
++    {
++      get { return regressionSolution; }
++      protected set
++      {
++        regressionSolution = value;
++        OnModelChanged();
++      }
++    }
++
++    private List<Tuple<RealVector, double>> TruncatedSamples => Samples.Count > SapbaAlgorithm.MaximalDatasetSize && SapbaAlgorithm.MaximalDatasetSize > 0 ? Samples.Skip(Samples.Count - SapbaAlgorithm.MaximalDatasetSize).ToList() : Samples;
+     #endregion
+ 
++    #region Events
++    public event EventHandler ModelChanged;
++    private void OnModelChanged() {
++      ModelChanged?.Invoke(this, EventArgs.Empty);
++      OnToStringChanged();
++    }
++    #endregion
++
+     #region ResultName
+     private const string BestQualityResultName = "Best Quality";
+     private const string BestSolutionResultName = "Best Solution";
+@@ -64,55 +82,44 @@
+     [StorableConstructor]
+     protected StrategyBase(bool deserializing) : base(deserializing) { }
+     protected StrategyBase(StrategyBase original, Cloner cloner) : base(original, cloner) {
+-      if (original.Samples != null) Samples = original.Samples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
++      Samples = original.Samples?.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
+       RegressionSolution = cloner.Clone(original.RegressionSolution);
++      SapbaAlgorithm = cloner.Clone(original.SapbaAlgorithm);
+     }
+     protected StrategyBase() { }
+     #endregion
+ 
+-    public abstract double Evaluate(RealVector r, IRandom random);
+     protected abstract void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, ResultCollection globalResults, IRandom random);
+     protected abstract void ProcessPopulation(Individual[] individuals, double[] qualities, IRandom random);
+-    protected abstract void Initialize();
++    protected virtual void Initialize() { }
++    //protected virtual void OnModelChanged() { }
+ 
++    protected abstract double Estimate(RealVector r, IRandom random);
++
++    public double Evaluate(RealVector r, IRandom random) {
++      if (Samples.Count < SapbaAlgorithm.InitialEvaluations) return EvaluateSample(r, random).Item2;
++      if (Samples.Count == SapbaAlgorithm.InitialEvaluations && RegressionSolution == null) {
++        BuildRegressionSolution(random);
++        OnModelChanged();
++      }
++      return Estimate(r, random);
++    }
+     public void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+-      Algorithm.Problem.Analyze(individuals, qualities, results, random);
++      SapbaAlgorithm.Problem.Analyze(individuals, qualities, results, random);
+       ProcessPopulation(individuals, qualities, random);
+ 
+-      var globalResults = Algorithm.Results;
++      var globalResults = SapbaAlgorithm.Results;
+       if (!globalResults.ContainsKey(EvaluatedSoultionsResultName)) globalResults.Add(new Result(EvaluatedSoultionsResultName, new IntValue(Samples.Count)));
+       else ((IntValue)globalResults[EvaluatedSoultionsResultName].Value).Value = Samples.Count;
+       if (!globalResults.ContainsKey(IterationsResultName)) globalResults.Add(new Result(IterationsResultName, new IntValue(0)));
+       else ((IntValue)globalResults[IterationsResultName].Value).Value++;
+ 
+-      if (Samples.Count != 0) {
+-        var min = Samples.Min(x => x.Item2);
+-        var max = Samples.Max(x => x.Item2);
+-        var bestIdx = Algorithm.Problem.Maximization ? Samples.ArgMax(x => x.Item2) : Samples.ArgMin(x => x.Item2);
+ 
+-        if (!globalResults.ContainsKey(BestQualityResultName)) globalResults.Add(new Result(BestQualityResultName, new DoubleValue(0.0)));
+-        ((DoubleValue)globalResults[BestQualityResultName].Value).Value = Samples[bestIdx].Item2;
+-        if (!globalResults.ContainsKey(BestSolutionResultName)) globalResults.Add(new Result(BestSolutionResultName, new RealVector()));
+-        globalResults[BestSolutionResultName].Value = Samples[bestIdx].Item1;
++      AnalyzeSamplesProgression(globalResults);
++      AnalyzeQualities(globalResults);
+ 
+-        DataTable table;
+-        if (!globalResults.ContainsKey(QualityTableResultName)) {
+-          table = new DataTable("Qualites", "Qualites over iteration");
+-          globalResults.Add(new Result(QualityTableResultName, table));
+-          table.Rows.Add(new DataRow(BestQualityRowName, "Best Quality"));
+-          table.Rows.Add(new DataRow(WorstQualityRowName, "Worst Quality"));
+-          table.Rows.Add(new DataRow(CurrentQualityRowName, "Current Quality"));
+-          table.Rows.Add(new DataRow(MedianQualityRowName, "Median Quality"));
+-          table.Rows.Add(new DataRow(AverageQualityRowName, "Average Quality"));
+-        }
+-        table = (DataTable)globalResults[QualityTableResultName].Value;
+-        table.Rows[BestQualityResultName].Values.Add(Algorithm.Problem.Maximization ? max : min);
+-        table.Rows[WorstQualityRowName].Values.Add(Algorithm.Problem.Maximization ? min : max);
+-        table.Rows[CurrentQualityRowName].Values.Add(Samples[Samples.Count - 1].Item2);
+-        table.Rows[AverageQualityRowName].Values.Add(Samples.Average(x => x.Item2));
+-        table.Rows[MedianQualityRowName].Values.Add(Samples.Select(x => x.Item2).Median());
+-      }
+ 
++
+       if (RegressionSolution != null) {
+         if (!globalResults.ContainsKey(RegressionSolutionResultName))
+           globalResults.Add(new Result(RegressionSolutionResultName, RegressionSolution));
+@@ -122,40 +129,93 @@
+ 
+       Analyze(individuals, qualities, results, globalResults, random);
+     }
++    private void AnalyzeSamplesProgression(ResultCollection globalResults) {
++      const string samplesTableName = "SamplesProgression";
++      const string minRowName = "Minimum";
++      const string maxRowName = "Maximum";
++      const string medianRowName = "Median";
++      const string averageRowName = "Average";
++      const string currentRowName = "Current";
++
++      if (!globalResults.ContainsKey(samplesTableName)) { globalResults.Add(new Result(samplesTableName, new DataTable())); }
++      var table = (DataTable)globalResults[samplesTableName].Value;
++
++      if (!table.Rows.ContainsKey(minRowName)) table.Rows.Add(new DataRow(minRowName));
++      if (!table.Rows.ContainsKey(maxRowName)) table.Rows.Add(new DataRow(maxRowName));
++      if (!table.Rows.ContainsKey(medianRowName)) table.Rows.Add(new DataRow(medianRowName));
++      if (!table.Rows.ContainsKey(averageRowName)) table.Rows.Add(new DataRow(averageRowName));
++      if (!table.Rows.ContainsKey(currentRowName)) table.Rows.Add(new DataRow(currentRowName));
++
++      for (var i = table.Rows[minRowName].Values.Count + 1; i < Samples.Count; i++) {
++        var subSamples = Samples.Take(i).Select(x => x.Item2).ToArray();
++        table.Rows[minRowName].Values.Add(subSamples.Min());
++        table.Rows[maxRowName].Values.Add(subSamples.Max());
++        table.Rows[medianRowName].Values.Add(subSamples.Median());
++        table.Rows[averageRowName].Values.Add(subSamples.Average());
++        table.Rows[currentRowName].Values.Add(subSamples[subSamples.Length - 1]);
++      }
++    }
++    private void AnalyzeQualities(ResultCollection globalResults) {
++      if (Samples.Count == 0) return;
++      var min = Samples.Min(x => x.Item2);
++      var max = Samples.Max(x => x.Item2);
++      var bestIdx = SapbaAlgorithm.Problem.Maximization ? Samples.ArgMax(x => x.Item2) : Samples.ArgMin(x => x.Item2);
++
++      if (!globalResults.ContainsKey(BestQualityResultName)) globalResults.Add(new Result(BestQualityResultName, new DoubleValue(0.0)));
++      ((DoubleValue)globalResults[BestQualityResultName].Value).Value = Samples[bestIdx].Item2;
++      if (!globalResults.ContainsKey(BestSolutionResultName)) globalResults.Add(new Result(BestSolutionResultName, new RealVector()));
++      globalResults[BestSolutionResultName].Value = Samples[bestIdx].Item1;
++
++      DataTable table;
++      if (!globalResults.ContainsKey(QualityTableResultName)) {
++        table = new DataTable("Qualites", "Qualites over iteration");
++        globalResults.Add(new Result(QualityTableResultName, table));
++        table.Rows.Add(new DataRow(BestQualityRowName, "Best Quality"));
++        table.Rows.Add(new DataRow(WorstQualityRowName, "Worst Quality"));
++        table.Rows.Add(new DataRow(CurrentQualityRowName, "Current Quality"));
++        table.Rows.Add(new DataRow(MedianQualityRowName, "Median Quality"));
++        table.Rows.Add(new DataRow(AverageQualityRowName, "Average Quality"));
++      }
++      table = (DataTable)globalResults[QualityTableResultName].Value;
++      table.Rows[BestQualityResultName].Values.Add(SapbaAlgorithm.Problem.Maximization ? max : min);
++      table.Rows[WorstQualityRowName].Values.Add(SapbaAlgorithm.Problem.Maximization ? min : max);
++      table.Rows[CurrentQualityRowName].Values.Add(Samples[Samples.Count - 1].Item2);
++      table.Rows[AverageQualityRowName].Values.Add(Samples.Average(x => x.Item2));
++      table.Rows[MedianQualityRowName].Values.Add(Samples.Select(x => x.Item2).Median());
++    }
++
+     public void Initialize(SurrogateAssistedPopulationBasedAlgorithm algorithm) {
+-      Algorithm = algorithm;
+-      Samples = algorithm.InitialSamples?.ToList() ?? new List<Tuple<RealVector, double>>();
++      SapbaAlgorithm = algorithm;
++      Samples = algorithm?.InitialSamples?.ToList() ?? new List<Tuple<RealVector, double>>();
+       RegressionSolution = null;
+       Initialize();
+     }
++    public virtual bool Maximization() {
++      return SapbaAlgorithm?.Problem?.Maximization ?? false;
++    }
+ 
+     #region Helpers for Subclasses
+     protected void BuildRegressionSolution(IRandom random) {
+-      RegressionSolution = EgoUtilities.BuildModel(Cancellation, TruncatedSamples, Algorithm.RegressionAlgorithm, random, Algorithm.RemoveDuplicates, RegressionSolution);
++      RegressionSolution = SapbaUtilities.BuildModel(TruncatedSamples, SapbaAlgorithm.RegressionAlgorithm, random, SapbaAlgorithm.RemoveDuplicates, RegressionSolution);
+     }
+     protected Tuple<RealVector, double> EvaluateSample(RealVector point, IRandom random) {
+-      Cancellation.ThrowIfCancellationRequested();
+-      if (Samples.Count >= Algorithm.MaximumEvaluations) { Algorithm.OptimizationAlgorithm.Stop(); return new Tuple<RealVector, double>(point, 0.0); }
+-      var p = new Tuple<RealVector, double>(point, Algorithm.Problem.Evaluate(GetIndividual(point), random));
++      if (Samples.Count >= SapbaAlgorithm.MaximumEvaluations) { SapbaAlgorithm.OptimizationAlgorithm.Stop(); return new Tuple<RealVector, double>(point, 0.0); }
++      var p = new Tuple<RealVector, double>((RealVector)point.Clone(), SapbaAlgorithm.Problem.Evaluate(GetIndividual(point), random));
+       Samples.Add(p);
+       return p;
+     }
+-    protected Tuple<RealVector, double> EstimateSample(RealVector point, IRandom random) {
+-      if (Samples.Count == Algorithm.InitialEvaluations && RegressionSolution == null) BuildRegressionSolution(random);
+-      return Samples.Count < Algorithm.InitialEvaluations ? EvaluateSample(point, random) : new Tuple<RealVector, double>(point, RegressionSolution.Model.GetEstimation(point));
++    protected double EstimateSample(RealVector r) {
++      return RegressionSolution.Model.GetEstimation(r);
+     }
++
+     #endregion
+ 
+     #region Helpers
+     private Individual GetIndividual(RealVector r) {
+       var scope = new Scope();
+-      scope.Variables.Add(new Variable(Algorithm.Problem.Encoding.Name, r));
+-      return new SingleEncodingIndividual(Algorithm.Problem.Encoding, scope);
++      scope.Variables.Add(new Variable(SapbaAlgorithm.Problem.Encoding.Name, r));
++      return new SingleEncodingIndividual(SapbaAlgorithm.Problem.Encoding, scope);
+     }
+-
+-    public void UpdateCancellation(CancellationToken cancellationToken) {
+-      Cancellation = cancellationToken;
+-    }
+     #endregion
+   }
+ }
+\ No newline at end of file
+Index: HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs
+===================================================================
+--- HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs	(revision 15449)
++++ HeuristicLab.Algorithms.SAPBA/SurrogateAssistedPopulationBasedAlgorithm.cs	(working copy)
+@@ -24,7 +24,6 @@
+ using System.Linq;
+ using System.Threading;
+ using HeuristicLab.Algorithms.DataAnalysis;
+-using HeuristicLab.Algorithms.SAPBA.Strategies;
+ using HeuristicLab.Common;
+ using HeuristicLab.Core;
+ using HeuristicLab.Data;
+@@ -33,7 +32,6 @@
+ using HeuristicLab.Parameters;
+ using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+ using HeuristicLab.Problems.DataAnalysis;
+-using HeuristicLab.Random;
+ 
+ namespace HeuristicLab.Algorithms.SAPBA {
+   [StorableClass]
+@@ -41,7 +39,7 @@
+   [Item("SurrogateAssistedPopulationBasedAlgorithm", "")]
+   public class SurrogateAssistedPopulationBasedAlgorithm : BasicAlgorithm, ISurrogateAlgorithm<RealVector> {
+     #region Basic-Alg-Essentials
+-    public override bool SupportsPause => true;
++    public override bool SupportsPause => false;
+     public override Type ProblemType => typeof(SingleObjectiveBasicProblem<IEncoding>);
+     public new SingleObjectiveBasicProblem<IEncoding> Problem
+     {
+@@ -91,14 +89,9 @@
+ 
+     #region StorableProperties 
+     [Storable]
+-    private IRandom Random = new MersenneTwister();
+-    [Storable]
+     public List<Tuple<RealVector, double>> InitialSamples { get; private set; }
+     [Storable]
+-    public SurrogateProblem surrogateProblem;
+-    public void SetInitialSamples(RealVector[] solutions, double[] qualities) {
+-      InitialSamples = solutions.Zip(qualities, (vector, d) => new Tuple<RealVector, double>(vector, d)).ToList();
+-    }
++    public SurrogateProblem SurrogateProblem;
+     #endregion
+ 
+     #region HLConstructors
+@@ -109,59 +102,50 @@
+       RegisterEventhandlers();
+     }
+     protected SurrogateAssistedPopulationBasedAlgorithm(SurrogateAssistedPopulationBasedAlgorithm original, Cloner cloner) : base(original, cloner) {
+-      Random = cloner.Clone(Random);
+-      if (original.InitialSamples != null) InitialSamples = original.InitialSamples.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
++      InitialSamples = original.InitialSamples?.Select(x => new Tuple<RealVector, double>(cloner.Clone(x.Item1), x.Item2)).ToList();
++      SurrogateProblem = cloner.Clone(original.SurrogateProblem);
+       RegisterEventhandlers();
+     }
+     public override IDeepCloneable Clone(Cloner cloner) { return new SurrogateAssistedPopulationBasedAlgorithm(this, cloner); }
+     public SurrogateAssistedPopulationBasedAlgorithm() {
+-      surrogateProblem = new SurrogateProblem();
+-      var geneticAlgorithm = new GeneticAlgorithm.GeneticAlgorithm {
+-        PopulationSize = { Value = 50 },
+-        Problem = surrogateProblem
+-      };
+-      var model = new GaussianProcessRegression {
+-        Problem = new RegressionProblem()
+-      };
++      SurrogateProblem = new SurrogateProblem();
++      var geneticAlgorithm = new GeneticAlgorithm.GeneticAlgorithm { PopulationSize = { Value = 50 }, Problem = SurrogateProblem, Elites = { Value = 0 } };
++      var model = new GaussianProcessRegression { Problem = new RegressionProblem() };
++      var strategies = new ItemSet<ISurrogateStrategy> { new InfillStrategy(), new LamarckianStrategy() };
++
+       model.CovarianceFunctionParameter.Value = new CovarianceRationalQuadraticIso();
+-
+-      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "", new IntValue(int.MaxValue)));
+-      Parameters.Add(new FixedValueParameter<IntValue>(InitialEvaluationsParameterName, "", new IntValue(10)));
++      Parameters.Add(new FixedValueParameter<IntValue>(InitialEvaluationsParameterName, "The initial number of evaluations performed before the first model is constructed", new IntValue(10)));
++      Parameters.Add(new FixedValueParameter<IntValue>(MaximalDataSetSizeParameterName, "The maximum number of sample points used to generate the model. Set 0 or less to use always all samples ", new IntValue(-1)));
++      Parameters.Add(new FixedValueParameter<IntValue>(MaximumEvaluationsParameterName, "The maximum number of evaluations performed", new IntValue(int.MaxValue)));
+       Parameters.Add(new FixedValueParameter<IntValue>(MaximumRuntimeParameterName, "The maximum runtime in seconds after which the algorithm stops. Use -1 to specify no limit for the runtime", new IntValue(-1)));
++      Parameters.Add(new ValueParameter<Algorithm>(OptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", geneticAlgorithm));
++      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", model));
++      Parameters.Add(new FixedValueParameter<BoolValue>(RemoveDuplicatesParamterName, "Wether duplicate samples should be replaced by a single sample with an averaged quality. This GREATLY decreases the chance of ill conditioned models (unbuildable models) but is not theoretically sound as the model ignores the increasing certainty in this region"));
+       Parameters.Add(new FixedValueParameter<IntValue>(SeedParameterName, "The random seed used to initialize the new pseudo random number generator.", new IntValue(0)));
+       Parameters.Add(new FixedValueParameter<BoolValue>(SetSeedRandomlyParameterName, "True if the random seed should be set to a random value, otherwise false.", new BoolValue(true)));
+-      Parameters.Add(new ValueParameter<IDataAnalysisAlgorithm<IRegressionProblem>>(RegressionAlgorithmParameterName, "The model used to approximate the problem", model));
+-      Parameters.Add(new ValueParameter<Algorithm>(OptimizationAlgorithmParameterName, "The algorithm used to solve the expected improvement subproblem", geneticAlgorithm));
+-      Parameters.Add(new FixedValueParameter<IntValue>(MaximalDataSetSizeParameterName, "The maximum number of sample points used to generate the model. Set 0 or less to use always all samples ", new IntValue(-1)));
+-      Parameters.Add(new FixedValueParameter<BoolValue>(RemoveDuplicatesParamterName, "Wether duplicate samples should be replaced by a single sample with an averaged quality. This GREATLY decreases the chance of ill conditioned models (unbuildable models) but is not theoretically sound as the model ignores the increasing certainty in this region"));
+-      var strategies = new ItemSet<ISurrogateStrategy> { new GenerationalStrategy(), new IndividualStrategy() };
+       Parameters.Add(new ConstrainedValueParameter<ISurrogateStrategy>(StrategyParameterName, "The surrogate strategy that dictates how the optimization alg is assisted", strategies, strategies.First()));
+       RegisterEventhandlers();
+     }
+     #endregion
+ 
++    public void SetInitialSamples(RealVector[] solutions, double[] qualities) {
++      InitialSamples = solutions.Zip(qualities, (vector, d) => new Tuple<RealVector, double>(vector, d)).ToList();
++    }
+     protected override void Initialize(CancellationToken cancellationToken) {
+       base.Initialize(cancellationToken);
+-      //encoding
+       var enc = Problem.Encoding as RealVectorEncoding;
+       if (enc == null) throw new ArgumentException("The SAPBA algorithm can only be applied to RealVectorEncodings");
+-
+-      //random
+       if (SetSeedRandomly) SeedParameter.Value.Value = new System.Random().Next();
+-      Random.Reset(Seed);
+-
+-      //initialize Strategy and Problem
+       SurrogateStrategy.Initialize(this);
+-      SurrogateStrategy.UpdateCancellation(cancellationToken);
+-      surrogateProblem.SetStrategy(SurrogateStrategy);
+-      surrogateProblem.SetProblem(Problem);
++      SurrogateProblem.Initialize(Problem, SurrogateStrategy);
+     }
+     protected override void Run(CancellationToken cancellationToken) {
+-      SurrogateStrategy.UpdateCancellation(cancellationToken);
+-      try { EgoUtilities.SyncRunSubAlgorithm(OptimizationAlgorithm, Random.Next()); }
+-      finally { Analyze(); }
++      try { SapbaUtilities.SyncRunSubAlgorithm(OptimizationAlgorithm, Seed); }
++      finally {
++        foreach (var surrogateStrategy in StrategyParameter.ValidValues) surrogateStrategy.Initialize(null);
++        OptimizationAlgorithm.Runs.Clear();
++      }
+     }
+-    private void Analyze() { }
+ 
+     #region Eventhandling
+     private void RegisterEventhandlers() {
+@@ -172,7 +156,7 @@
+       OptimizationAlgorithmParameter.ValueChanged -= OnOptimizationAlgorithmChanged;
+     }
+     private void OnOptimizationAlgorithmChanged(object sender, EventArgs e) {
+-      OptimizationAlgorithm.Problem = surrogateProblem;
++      OptimizationAlgorithm.Problem = SurrogateProblem;
+     }
+ 
+     protected override void OnExecutionTimeChanged() {
+@@ -179,23 +163,18 @@
+       base.OnExecutionTimeChanged();
+       if (CancellationTokenSource == null) return;
+       if (MaximumRuntime == -1) return;
+-      if (ExecutionTime.TotalSeconds > MaximumRuntime) CancellationTokenSource.Cancel();
++      if (ExecutionTime.TotalSeconds > MaximumRuntime) OptimizationAlgorithm.Stop();
+     }
+     public override void Pause() {
+       base.Pause();
+-      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Pause();
+-      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started) OptimizationAlgorithm.Pause();
+-
++      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Stop();
++      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started) OptimizationAlgorithm.Stop();
+     }
+     public override void Stop() {
+       base.Stop();
+-      if (RegressionAlgorithm.ExecutionState == ExecutionState.Started) RegressionAlgorithm.Stop();
+-      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started) OptimizationAlgorithm.Stop();
++      //if (RegressionAlgorithm.ExecutionState == ExecutionState.Started || RegressionAlgorithm.ExecutionState == ExecutionState.Paused) RegressionAlgorithm.Stop();
++      if (OptimizationAlgorithm.ExecutionState == ExecutionState.Started || OptimizationAlgorithm.ExecutionState == ExecutionState.Paused) OptimizationAlgorithm.Stop();
+     }
+-    protected override void OnProblemChanged() {
+-      base.OnProblemChanged();
+-      surrogateProblem.SetProblem(Problem);
+-    }
+     #endregion
+ 
+   }
