Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/AssistedOptimizerProblem.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/AssistedOptimizerProblem.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/AssistedOptimizerProblem.cs	(revision 15896)
@@ -0,0 +1,93 @@
+﻿using System;
+using System.Linq;
+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.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Assisted Optimizer Problem", "")]
+  [StorableClass]
+  public sealed class AssistedOptimizerProblem : SingleObjectiveBasicProblem<RealVectorEncoding> {
+    private const string RegressionSolutionParameterName = "RegressionSolution";
+    private const string OptimizeExpectedImprovementParameterName = "OptimizeExpectedImprovement";
+
+    public IValueParameter<IRegressionSolution> RegressionSolutionParameter {
+      get { return (IValueParameter<IRegressionSolution>)Parameters[RegressionSolutionParameterName]; }
+    }
+
+    public IValueParameter<BoolValue> OptimizeExpectedImprovementParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[OptimizeExpectedImprovementParameterName]; }
+    }
+
+    public IRegressionSolution RegressionSolution {
+      get { return RegressionSolutionParameter.Value; }
+      set { RegressionSolutionParameter.Value = value; }
+    }
+
+    public BoolValue OptimizeExpectedImprovement {
+      get { return OptimizeExpectedImprovementParameter.Value; }
+      set { OptimizeExpectedImprovementParameter.Value = value; }
+    }
+
+    public Action<RealVector, double> NotifyEvaluation { get; set; }
+
+    public override bool Maximization {
+      get { return false; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private AssistedOptimizerProblem(bool deserializing) : base(deserializing) { }
+    private AssistedOptimizerProblem(AssistedOptimizerProblem original, Cloner cloner) : base(original, cloner) { }
+    public AssistedOptimizerProblem() {
+      Parameters.Add(new ValueParameter<IRegressionSolution>(RegressionSolutionParameterName, ""));
+      Parameters.Add(new ValueParameter<BoolValue>(OptimizeExpectedImprovementParameterName, "", new BoolValue(true)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AssistedOptimizerProblem(this, cloner);
+    }
+    #endregion
+
+    public override double Evaluate(Individual individual, IRandom random) {
+      var point = individual.RealVector();
+      var solution = RegressionSolutionParameter.Value;
+      var useExpectedImprovement = OptimizeExpectedImprovement.Value;
+
+      var result = ExpectedImprovementHelpers.Evaluate(new[] { point }, solution, useExpectedImprovement).Single();
+      var target = useExpectedImprovement ? -result : result;
+
+      NotifyEvaluation((RealVector)point.Clone(), target);
+
+      return target;
+    }
+
+    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(individuals, qualities, results, random);
+
+      var bestIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).MinItems(x => x.Quality);
+      var best = bestIndividuals.First();
+
+      IResult bestSolutionResult;
+      if (!results.TryGetValue("BestSolution", out bestSolutionResult)) {
+        results.Add(bestSolutionResult = new Result("BestSolution", typeof(RealVector)));
+      } else bestSolutionResult = results["BestSolution"];
+
+      IResult bestQualityResult;
+      if (!results.TryGetValue("BestQuality", out bestQualityResult)) {
+        results.Add(bestQualityResult = new Result("BestQuality", typeof(DoubleValue)));
+      } else bestQualityResult = results["BestQuality"];
+
+      var bestQuality = (DoubleValue)bestQualityResult.Value;
+      if (bestQuality == null || best.Quality <= bestQuality.Value) {
+        bestSolutionResult.Value = (RealVector)best.Individual.RealVector().Clone();
+        bestQualityResult.Value = new DoubleValue(best.Quality);
+      }
+    }
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/ExpectedImprovementHelpers.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/ExpectedImprovementHelpers.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/ExpectedImprovementHelpers.cs	(revision 15896)
@@ -0,0 +1,47 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  public static class ExpectedImprovementHelpers {
+    public static IEnumerable<double> Evaluate(IEnumerable<RealVector> points, IRegressionSolution solution, bool calculateExpectedImprovement = true) {
+      var model = solution.Model;
+      var problemData = solution.ProblemData;
+      var dataset = problemData.Dataset;
+
+      var modifiableDataset = new ModifiableDataset(problemData.AllowedInputVariables, problemData.AllowedInputVariables.Select(x => new List<double>()));
+      foreach (var point in points)
+        modifiableDataset.AddRow(point.Select(x => (object)x));
+
+      var targets = model.GetEstimatedValues(modifiableDataset, Enumerable.Range(0, modifiableDataset.Rows))
+                         .ToArray();
+
+      if (calculateExpectedImprovement) {
+        var confModel = model as IConfidenceRegressionModel;
+        if (confModel != null) {
+          var minTarget = dataset.GetDoubleValues(problemData.TargetVariable).ToList().Min();
+          var uncertainties = confModel.GetEstimatedVariances(modifiableDataset, Enumerable.Range(0, modifiableDataset.Rows))
+                                       .Select(Math.Sqrt)
+                                       .ToArray();
+          for (int i = 0; i < modifiableDataset.Rows; i++)
+            targets[i] = CalculateExpectedImprovement(minTarget, targets[i], uncertainties[i]);
+        }
+      }
+
+      return targets;
+    }
+
+    private static double CalculateExpectedImprovement(double bestTarget, double estimatedTarget, double modelUncertainty) {
+      if (modelUncertainty.IsAlmost(0.0)) return 0.0;
+
+      var delta = bestTarget - estimatedTarget;
+      var x = delta / modelUncertainty;
+      var expImp = delta * alglib.normaldistribution(x) + modelUncertainty * Math.Exp(-0.5 * x * x) / Math.Sqrt(2 * Math.PI);
+
+      return double.IsNaN(expImp) || double.IsInfinity(expImp) ? 0.0 : expImp;
+    }
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluationAlgorithm.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluationAlgorithm.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluationAlgorithm.cs	(revision 15896)
@@ -0,0 +1,282 @@
+﻿using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+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;
+using HeuristicLab.Problems.TestFunctions;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Full Evaluation Algorithm", "")]
+  [Creatable]
+  [StorableClass]
+  public sealed class FullEvaluationAlgorithm : BasicAlgorithm {
+    private readonly object locker = new object();
+
+    private SemaphoreSlim tickets;
+    private LimitedPriorityQueue exploitationQueue;
+    private LimitedPriorityQueue explorationQueue;
+
+    public override bool SupportsPause { get { return true; } }
+
+    public override Type ProblemType { get { return typeof(SingleObjectiveTestFunctionProblem); } }
+    public new SingleObjectiveTestFunctionProblem Problem {
+      get { return (SingleObjectiveTestFunctionProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    public Action<RealVector, double> NotifyEvaluation { get; set; }
+
+    #region Parameter Names
+    private const string MaxEvaluationsParameterName = "MaxEvaluations";
+    private const string MaxConcurrentEvaluationsParameterName = "MaxConcurrentEvaluations";
+    private const string MaxBufferLengthParameterName = "MaxBufferLength";
+    private const string AdditionalEvaluationDurationParameterName = "AdditionalEvaluationDuration";
+    private const string RegressionSolutionParameterName = "RegressionSolution";
+    private const string SortAccordingToExpectedImprovementParameterName = "SortAccordingToExpectedImprovement";
+    #endregion Parameter Names
+
+    #region Parameters
+    public IValueParameter<IntValue> MaxEvaluationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxEvaluationsParameterName]; }
+    }
+
+    public IValueParameter<IntValue> MaxConcurrentEvaluationsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxConcurrentEvaluationsParameterName]; }
+    }
+
+    public IValueParameter<IntValue> MaxBufferLengthParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxBufferLengthParameterName]; }
+    }
+
+    public IValueParameter<TimeSpanValue> AdditionalEvaluationDurationParameter {
+      get { return (IValueParameter<TimeSpanValue>)Parameters[AdditionalEvaluationDurationParameterName]; }
+    }
+
+    public IValueParameter<IRegressionSolution> RegressionSolutionParameter {
+      get { return (IValueParameter<IRegressionSolution>)Parameters[RegressionSolutionParameterName]; }
+    }
+
+    public IValueParameter<BoolValue> SortAccordingToExpectedImprovementParameter {
+      get { return (IValueParameter<BoolValue>)Parameters[SortAccordingToExpectedImprovementParameterName]; }
+    }
+    #endregion Parameters
+
+    #region Parameter Properties
+    private IntValue MaxEvaluations {
+      get { return MaxEvaluationsParameter.Value; }
+      set { MaxEvaluationsParameter.Value = value; }
+    }
+
+    public int MaxConcurrentEvaluations {
+      get { return MaxConcurrentEvaluationsParameter.Value.Value; }
+      set { MaxConcurrentEvaluationsParameter.Value.Value = value; }
+    }
+
+    public int MaxBufferLength {
+      get { return MaxBufferLengthParameter.Value.Value; }
+      set { MaxBufferLengthParameter.Value.Value = value; }
+    }
+
+    public TimeSpan AdditionalEvaluationDuration {
+      get { return AdditionalEvaluationDurationParameter.Value.Value; }
+      set { AdditionalEvaluationDurationParameter.Value.Value = value; }
+    }
+
+    public IRegressionSolution RegressionSolution {
+      get { return RegressionSolutionParameter.Value; }
+      set { RegressionSolutionParameter.Value = value; }
+    }
+
+    public BoolValue SortAccordingToExpectedImprovement {
+      get { return SortAccordingToExpectedImprovementParameter.Value; }
+      set { SortAccordingToExpectedImprovementParameter.Value = value; }
+    }
+    #endregion Parameter Properties
+
+    #region Result Names
+    private const string EvaluatedSolutionsResultName = "EvaluatedSolutions";
+    private const string EvaluatedExplorationSolutionsResultName = "EvaluatedExplorationSolutions";
+    private const string EvaluatedExploitationSolutionsResultName = "EvaluatedExploitationSolutions";
+    private const string FullEvaluationQualitiesResultName = "FullEvaluationQualities";
+    #endregion Result Names
+
+    #region Results
+    private IntValue EvaluatedSolutionsResult {
+      get { return (IntValue)Results[EvaluatedSolutionsResultName].Value; }
+    }
+
+    private IItemList<RealVector> EvaluatedExplorationSolutionsResult {
+      get { return (IItemList<RealVector>)Results[EvaluatedExplorationSolutionsResultName].Value; }
+    }
+
+    private IItemList<RealVector> EvaluatedExploitationSolutionsResult {
+      get { return (IItemList<RealVector>)Results[EvaluatedExploitationSolutionsResultName].Value; }
+    }
+
+    private DataTable FullEvaluationQualitiesResult {
+      get { return (DataTable)Results[FullEvaluationQualitiesResultName].Value; }
+    }
+    #endregion Results
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private FullEvaluationAlgorithm(bool deserializing) : base(deserializing) { }
+    private FullEvaluationAlgorithm(FullEvaluationAlgorithm original, Cloner cloner) : base(original, cloner) {
+      RegressionSolutionParameter.ValueChanged += RegressionSolutionParameter_ValueChanged;
+    }
+    public FullEvaluationAlgorithm() {
+      Parameters.Add(new ValueParameter<IntValue>(MaxEvaluationsParameterName, new IntValue(200)));
+      Parameters.Add(new ValueParameter<IntValue>(MaxConcurrentEvaluationsParameterName, new IntValue(1)));
+      Parameters.Add(new ValueParameter<IntValue>(MaxBufferLengthParameterName, new IntValue(100)));
+      Parameters.Add(new ValueParameter<TimeSpanValue>(AdditionalEvaluationDurationParameterName, new TimeSpanValue(TimeSpan.FromSeconds(5.0))));
+      Parameters.Add(new ValueParameter<IRegressionSolution>(RegressionSolutionParameterName, ""));
+      Parameters.Add(new ValueParameter<BoolValue>(SortAccordingToExpectedImprovementParameterName, "", new BoolValue(true)));
+
+      RegressionSolutionParameter.ValueChanged += RegressionSolutionParameter_ValueChanged;
+
+      Problem = new SingleObjectiveTestFunctionProblem();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FullEvaluationAlgorithm(this, cloner);
+    }
+    #endregion Constructors & Cloning
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegressionSolutionParameter.ValueChanged += RegressionSolutionParameter_ValueChanged;
+    }
+
+    private void RegressionSolutionParameter_ValueChanged(object sender, EventArgs e) {
+      lock (exploitationQueue) {
+        var points = exploitationQueue.Select(x => x.Item2).ToArray();
+        var solution = RegressionSolutionParameter.Value;
+        var useExpectedImprovement = SortAccordingToExpectedImprovement.Value;
+
+        var results = ExpectedImprovementHelpers.Evaluate(points, solution, useExpectedImprovement);
+        var targets = (useExpectedImprovement ? results.Select(x => -x) : results).ToArray();
+
+        exploitationQueue.Clear();
+        for (int i = 0; i < points.Length; i++)
+          exploitationQueue.Enqueue(targets[i], points[i]);
+      }
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      var maxConcurrentEvals = MaxConcurrentEvaluationsParameter.Value.Value;
+      tickets = new SemaphoreSlim(maxConcurrentEvals, maxConcurrentEvals);
+
+      var maxBufferLength = MaxBufferLengthParameter.Value.Value;
+      exploitationQueue = new LimitedPriorityQueue(maxBufferLength, new LimitedPriorityQueue.AscendingPriorityComparer());
+      explorationQueue = new LimitedPriorityQueue(maxBufferLength, new LimitedPriorityQueue.DescendingPriorityComparer());
+
+      Results.Add(new Result(EvaluatedSolutionsResultName, new IntValue(0)));
+      Results.Add(new Result(EvaluatedExplorationSolutionsResultName, new ItemList<RealVector>()));
+      Results.Add(new Result(EvaluatedExploitationSolutionsResultName, new ItemList<RealVector>()));
+      Results.Add(new Result(FullEvaluationQualitiesResultName, new DataTable(FullEvaluationQualitiesResultName) {
+        Rows = { new DataRow("Exploration"), new DataRow("Exploitation"), new DataRow("Best") }
+      }));
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      bool doExploration = false;
+
+      while (!cancellationToken.IsCancellationRequested && EvaluatedSolutionsResult.Value < MaxEvaluations.Value) {
+        try { tickets.Wait(cancellationToken); } catch (OperationCanceledException) { break; }
+
+        RealVector realVector;
+        if (doExploration = !doExploration) {
+          lock (explorationQueue) {
+            if (explorationQueue.TryDequeue(out realVector)) {
+              DoFullEvaluationAsync(realVector, EvaluationSolutionType.Exploration, cancellationToken);
+            } else {
+              tickets.Release();
+            }
+          }
+        } else {
+          lock (exploitationQueue) {
+            if (exploitationQueue.TryDequeue(out realVector)) {
+              DoFullEvaluationAsync(realVector, EvaluationSolutionType.Exploitation, cancellationToken);
+            } else {
+              tickets.Release();
+            }
+          }
+        }
+      }
+
+      for (int i = 0; i < tickets.CurrentCount; i++) tickets.Release();
+
+      // signal that we are done ...
+      NotifyEvaluation(new RealVector(), double.NaN); // TODO: improve this
+    }
+
+    #region Helpers
+    private enum EvaluationSolutionType { Exploration, Exploitation }
+
+    public void EnqueueForExploitation(RealVector realVector, double priority) {
+      lock (exploitationQueue) exploitationQueue.Enqueue(priority, realVector);
+    }
+
+    public void EnqueueForExploration(RealVector realVector, double priority) {
+      lock (explorationQueue) explorationQueue.Enqueue(priority, realVector);
+    }
+
+    private async Task DoFullEvaluationAsync(RealVector realVector, EvaluationSolutionType evaluationSolutionType, CancellationToken cancellationToken) {
+      var quality = double.NaN;
+
+      try {
+        await Task.Delay(AdditionalEvaluationDurationParameter.Value.Value, cancellationToken);
+        quality = Problem.Evaluator.Evaluate(realVector);
+      } catch (OperationCanceledException) {
+      } finally {
+        tickets.Release();
+      }
+
+      if (EvaluatedSolutionsResult.Value >= MaxEvaluations.Value) return;
+
+      lock (locker) {
+        EvaluatedSolutionsResult.Value++;
+
+        var explorationValues = FullEvaluationQualitiesResult.Rows["Exploration"].Values;
+        var actualExplorationValues = explorationValues.Where(x => !double.IsNaN(x));
+        var minExplorationValue = actualExplorationValues.Where(x => !double.IsNaN(x)).Any() ? actualExplorationValues.Min() : double.MaxValue;
+        var lastExplorationValue = actualExplorationValues.Any() ? actualExplorationValues.Last() : double.NaN;
+
+        var exploitationValues = FullEvaluationQualitiesResult.Rows["Exploitation"].Values;
+        var actualExploitationValues = exploitationValues.Where(x => !double.IsNaN(x));
+        var minExploitationValue = actualExploitationValues.Any() ? actualExploitationValues.Min() : double.MaxValue;
+        var lastExploitationValue = actualExploitationValues.Any() ? actualExploitationValues.Last() : double.NaN;
+
+        switch (evaluationSolutionType) {
+          case EvaluationSolutionType.Exploration:
+            EvaluatedExplorationSolutionsResult.Add(realVector);
+            explorationValues.Add(quality);
+            exploitationValues.Add(lastExploitationValue);
+            break;
+          case EvaluationSolutionType.Exploitation:
+            EvaluatedExploitationSolutionsResult.Add(realVector);
+            exploitationValues.Add(quality);
+            explorationValues.Add(lastExplorationValue);
+            break;
+          default: throw new ArgumentOutOfRangeException();
+        }
+
+        var minEvaluatedValue = Math.Min(minExplorationValue, minExploitationValue);
+        var minValue = Math.Min(minEvaluatedValue, quality);
+
+        FullEvaluationQualitiesResult.Rows["Best"].Values.Add(minValue);
+      }
+
+      NotifyEvaluation((RealVector)realVector.Clone(), quality);
+    }
+    #endregion Helpers
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluatorNode.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluatorNode.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/FullEvaluatorNode.cs	(revision 15896)
@@ -0,0 +1,90 @@
+﻿using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Networks;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Full Evaluator", "")]
+  [StorableClass]
+  public sealed class FullEvaluatorNode : OrchestratedAlgorithmNode {
+    public new FullEvaluationAlgorithm Algorithm {
+      get { return (FullEvaluationAlgorithm)base.Algorithm; }
+      set { base.Algorithm = value; }
+    }
+
+    #region Port Names
+    private const string ExploitationFullEvalRequestPortName = "ExploitationFullEvalRequestPort";
+    private const string ExplorationFullEvalRequestPortName = "ExplorationFullEvalRequestPort";
+    private const string UpdateRegressionSolutionPortName = "Update RegressionSolution";
+    #endregion Port Names
+
+    #region Ports
+    public IMessagePort ExploitationFullEvalRequestPort { get { return (IMessagePort)Ports[ExploitationFullEvalRequestPortName]; } }
+    public IMessagePort ExplorationFullEvalRequestPort { get { return (IMessagePort)Ports[ExplorationFullEvalRequestPortName]; } }
+    public IConfigurationPort UpdateRegressionSolutionPort { get { return (IConfigurationPort)Ports[UpdateRegressionSolutionPortName]; } }
+    #endregion Ports
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private FullEvaluatorNode(bool deserializing) : base(deserializing) { }
+    private FullEvaluatorNode(FullEvaluatorNode original, Cloner cloner) : base(original, cloner) {
+      RegisterPortEvents();
+    }
+    public FullEvaluatorNode() : this("Full Evaluator") { }
+    public FullEvaluatorNode(string name) : base(name) {
+      var exploitationPort = CreateEvaluationPort<RealVector>(ExploitationFullEvalRequestPortName, "RealVector", "Quality");
+      Ports.Add(exploitationPort);
+
+      var explorationPort = CreateEvaluationPort<RealVector>(ExplorationFullEvalRequestPortName, "RealVector", "Quality");
+      Ports.Add(explorationPort);
+
+      var updatePort = new ConfigurationPort(UpdateRegressionSolutionPortName) {
+        Parameters = {
+          new PortParameter<IRegressionSolution>("RegressionSolution") {
+            Type = PortParameterType.Input
+          }
+        }
+      };
+      Ports.Add(updatePort);
+
+      Algorithm = new FullEvaluationAlgorithm();
+
+      RegisterPortEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new FullEvaluatorNode(this, cloner);
+    }
+    #endregion Constructors & Cloning
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterPortEvents();
+    }
+
+    #region Helpers
+    private void RegisterPortEvents() {
+      ExploitationFullEvalRequestPort.MessageReceived += ExploitationFullEvalRequestPort_MessageReceived;
+      ExplorationFullEvalRequestPort.MessageReceived += ExplorationFullEvalRequestPort_MessageReceived;
+    }
+
+    private void ExploitationFullEvalRequestPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      var realVector = (RealVector)evalMsg["RealVector"];
+      var quality = (DoubleValue)evalMsg["Quality"];
+      Algorithm.EnqueueForExploitation(realVector, quality.Value);
+    }
+
+    private void ExplorationFullEvalRequestPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      var realVector = (RealVector)evalMsg["RealVector"];
+      var quality = (DoubleValue)evalMsg["Quality"];
+      Algorithm.EnqueueForExploration(realVector, quality.Value);
+    }
+    #endregion Helpers
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3.csproj
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3.csproj	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3.csproj	(revision 15896)
@@ -0,0 +1,248 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" 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>{12819229-8D69-44A3-9EF4-5A95D833F205}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling</RootNamespace>
+    <AssemblyName>HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x64</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
+    <DebugSymbols>true</DebugSymbols>
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <DebugType>full</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
+    <OutputPath>..\..\..\..\trunk\bin\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <Optimize>true</Optimize>
+    <DebugType>pdbonly</DebugType>
+    <PlatformTarget>x86</PlatformTarget>
+    <ErrorReport>prompt</ErrorReport>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="ALGLIB-3.7.0, Version=3.7.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\ALGLIB-3.7.0.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.ALPS-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.ALPS-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.GeneticAlgorithm-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.GeneticAlgorithm-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.LocalSearch-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.LocalSearch-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.NSGA2-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.NSGA2-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Algorithms.RandomSearch-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Algorithms.RandomSearch-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Analysis-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Analysis-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Collections-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Common-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Common-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Core-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Data-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.IntegerVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Encodings.IntegerVectorEncoding-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.RealVectorEncoding-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Encodings.RealVectorEncoding-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Encodings.SymbolicExpressionTreeEncoding-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Networks-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Networks-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec">
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Optimization.Operators-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Optimization.Operators-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Parameters-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Parameters-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Persistence-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4, Version=3.4.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.DataAnalysis.Symbolic.Regression-3.4.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.Instances-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.Instances-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.Problems.TestFunctions-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\trunk\bin\HeuristicLab.Problems.TestFunctions-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="HeuristicLab.SimGenOpt-3.3">
+      <HintPath>..\..\..\..\..\Project_SimGenOpt2\HL\trunk\bin\HeuristicLab.SimGenOpt-3.3.dll</HintPath>
+      <Private>False</Private>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <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="ExpectedImprovementHelpers.cs" />
+    <Compile Include="FullEvaluationAlgorithm.cs" />
+    <Compile Include="FullEvaluatorNode.cs" />
+    <Compile Include="LimitedPriorityQueue.cs" />
+    <Compile Include="PointGeneratorProblem.cs" />
+    <Compile Include="SurrogateModelingNetwork.cs" />
+    <Compile Include="AssistedOptimizerProblem.cs" />
+    <Compile Include="SurrogateModelingOrchestrator.cs" />
+    <None Include="Plugin.cs.frame" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="HeuristicLab.snk" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Networks.IntegratedOptimization\3.3\HeuristicLab.Networks.IntegratedOptimization-3.3.csproj">
+      <Project>{b6263d3e-dcaf-42b0-a440-3deef1ff0429}</Project>
+      <Name>HeuristicLab.Networks.IntegratedOptimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+  </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>
+</Project>
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/LimitedPriorityQueue.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/LimitedPriorityQueue.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/LimitedPriorityQueue.cs	(revision 15896)
@@ -0,0 +1,124 @@
+﻿using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Encodings.RealVectorEncoding;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  public class LimitedPriorityQueue : IEnumerable<Tuple<double, RealVector>> {
+    public class AscendingPriorityComparer : IComparer<double> {
+      public int Compare(double x, double y) {
+        return x.CompareTo(y);
+      }
+    }
+
+    public class DescendingPriorityComparer : IComparer<double> {
+      public int Compare(double x, double y) {
+        return y.CompareTo(x);
+      }
+    }
+
+    private class LimitedPriorityQueueComparer : IComparer<Tuple<double, RealVector>> {
+      private IComparer<double> comparer;
+      public LimitedPriorityQueueComparer(IComparer<double> priorityComparer) {
+        comparer = priorityComparer;
+      }
+
+      public int Compare(Tuple<double, RealVector> x, Tuple<double, RealVector> y) {
+        return comparer.Compare(x.Item1, y.Item1);
+      }
+    }
+
+    private readonly object locker = new object();
+    private readonly List<Tuple<double, RealVector>> list = new List<Tuple<double, RealVector>>();
+    private readonly HashSet<RealVector> hashes = new HashSet<RealVector>(new RealVectorEqualityComparer());
+
+    private readonly LimitedPriorityQueueComparer comparer;
+    private readonly SemaphoreSlim semaphore;
+    private readonly int limit;
+    private bool addingCompleted;
+
+    public int Count {
+      get { lock (locker) return list.Count; }
+    }
+
+    public bool IsAddingCompleted {
+      get { lock (locker) return addingCompleted; }
+    }
+
+    public LimitedPriorityQueue(int maxCount, IComparer<double> priorityComparer) {
+      limit = maxCount;
+      comparer = new LimitedPriorityQueueComparer(priorityComparer);
+      semaphore = new SemaphoreSlim(0, limit);
+    }
+
+    public bool Contains(RealVector value) {
+      lock (locker) return hashes.Contains(value);
+
+    }
+
+    public void Enqueue(double priority, RealVector value) {
+      lock (locker) {
+        var tuple = Tuple.Create(priority, value);
+        int index = list.BinarySearch(tuple, comparer);
+        if (index < 0) index = ~index;
+
+        if (list.Count == limit) {
+          var lastIndex = limit - 1;
+          var last = list[lastIndex];
+          list.RemoveAt(lastIndex);
+          hashes.Remove(last.Item2);
+        }
+
+        list.Insert(Math.Min(index, list.Count), tuple);
+        hashes.Add(value);
+
+        if (semaphore.CurrentCount < limit)
+          semaphore.Release();
+      }
+    }
+
+    public bool TryDequeue(out RealVector item) {
+      if (semaphore.Wait(0)) {
+        lock (locker) {
+          if (list.Any()) {
+            item = list[0].Item2;
+            list.RemoveAt(0);
+            hashes.Remove(item);
+            return true;
+          }
+        }
+      }
+
+      item = default(RealVector);
+      return false;
+    }
+
+    public Tuple<double, RealVector> LastOrDefault() {
+      lock (locker) return list.LastOrDefault();
+    }
+
+    public void Clear() {
+      lock (locker) {
+        list.Clear();
+        hashes.Clear();
+
+        for (int i = 0; i < semaphore.CurrentCount; i++)
+          semaphore.Wait();
+      }
+    }
+
+    public void CompleteAdding() {
+      lock (locker) addingCompleted = true;
+    }
+
+    public IEnumerator<Tuple<double, RealVector>> GetEnumerator() {
+      return list.GetEnumerator();
+    }
+
+    IEnumerator IEnumerable.GetEnumerator() {
+      return ((IEnumerable)list).GetEnumerator();
+    }
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Plugin.cs.frame
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Plugin.cs.frame	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Plugin.cs.frame	(revision 15896)
@@ -0,0 +1,32 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 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.PluginInfrastructure;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  /// <summary>
+  /// Plugin class for HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling plugin.
+  /// </summary>
+  [Plugin("HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling", "3.3.14.$WCREV$")]
+  [PluginFile("HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3.dll", PluginFileType.Assembly)]
+  public class HeuristicLabNetworksIntegratedOptimizationSurrogateModelingPlugin : PluginBase {
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/PointGeneratorProblem.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/PointGeneratorProblem.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/PointGeneratorProblem.cs	(revision 15896)
@@ -0,0 +1,64 @@
+﻿using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.RealVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Point Generator Problem", "")]
+  [StorableClass]
+  public sealed class PointGeneratorProblem : SingleObjectiveBasicProblem<RealVectorEncoding> {
+    public Action<RealVector, double> NotifyEvaluation { get; set; }
+
+    public override bool Maximization {
+      get { return false; }
+    }
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private PointGeneratorProblem(bool deserializing) : base(deserializing) { }
+    private PointGeneratorProblem(PointGeneratorProblem original, Cloner cloner) : base(original, cloner) { }
+    public PointGeneratorProblem() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+
+      return new PointGeneratorProblem(this, cloner);
+    }
+    #endregion
+
+    public override double Evaluate(Individual individual, IRandom random) {
+      var point = individual.RealVector();
+      var quality = 0.0;
+
+      NotifyEvaluation((RealVector)point.Clone(), quality);
+
+      return quality;
+    }
+
+    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
+      base.Analyze(individuals, qualities, results, random);
+
+      var bestIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).MinItems(x => x.Quality);
+      var best = bestIndividuals.First();
+
+      IResult bestSolutionResult;
+      if (!results.TryGetValue("BestSolution", out bestSolutionResult)) {
+        results.Add(bestSolutionResult = new Result("BestSolution", typeof(RealVector)));
+      } else bestSolutionResult = results["BestSolution"];
+
+      IResult bestQualityResult;
+      if (!results.TryGetValue("BestQuality", out bestQualityResult)) {
+        results.Add(bestQualityResult = new Result("BestQuality", typeof(DoubleValue)));
+      } else bestQualityResult = results["BestQuality"];
+
+      var bestQuality = (DoubleValue)bestQualityResult.Value;
+      if (bestQuality == null || best.Quality <= bestQuality.Value) {
+        bestSolutionResult.Value = (RealVector)best.Individual.RealVector().Clone();
+        bestQualityResult.Value = new DoubleValue(best.Quality);
+      }
+    }
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Properties/AssemblyInfo.cs.frame	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/Properties/AssemblyInfo.cs.frame	(revision 15896)
@@ -0,0 +1,36 @@
+﻿using System.Reflection;
+using System.Runtime.CompilerServices;
+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.Networks.IntegratedOptimization.SurrogateModeling")]
+[assembly: AssemblyDescription("Classes for integrated optimization of surrogate models")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeursiticLab")]
+[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("12819229-8d69-44a3-9ef4-5a95d833f205")]
+
+// 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("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.14.$WCREV$")]
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingNetwork.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingNetwork.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingNetwork.cs	(revision 15896)
@@ -0,0 +1,167 @@
+﻿using System;
+using HeuristicLab.Algorithms.ALPS;
+using HeuristicLab.Algorithms.DataAnalysis;
+using HeuristicLab.Algorithms.RandomSearch;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Networks;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Problems.DataAnalysis;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Surrogate Modeling Network", "")]
+  [Creatable("Optimization Networks")]
+  [StorableClass]
+  public sealed class SurrogateModelingNetwork : Network {
+    #region Nodes
+    [Storable]
+    private SurrogateModelingOrchestrator orchestrator;
+    private SurrogateModelingOrchestrator Orchestrator {
+      get { return orchestrator; }
+      set {
+        if (orchestrator != null)
+          throw new InvalidOperationException("Orchestrator has already been initialized.");
+        orchestrator = value;
+      }
+    }
+
+    [Storable]
+    private FullEvaluatorNode fullEvaluatorNode;
+    private FullEvaluatorNode FullEvaluatorNode {
+      get { return fullEvaluatorNode; }
+      set {
+        if (fullEvaluatorNode != null)
+          throw new InvalidOperationException("FullEvaluatorNode has already been initialized.");
+        fullEvaluatorNode = value;
+      }
+    }
+
+    [Storable]
+    private OrchestratedAlgorithmNode pointGeneratorNode;
+    private OrchestratedAlgorithmNode PointGeneratorNode {
+      get { return pointGeneratorNode; }
+      set {
+        if (pointGeneratorNode != null)
+          throw new InvalidOperationException("PointGeneratorNode has already been initialized.");
+        pointGeneratorNode = value;
+      }
+    }
+
+    [Storable]
+    private OrchestratedAlgorithmNode modelBuilderNode;
+    private OrchestratedAlgorithmNode ModelBuilderNode {
+      get { return modelBuilderNode; }
+      set {
+        if (modelBuilderNode != null)
+          throw new InvalidOperationException("ModelBuilderNode has already been initialized.");
+        modelBuilderNode = value;
+      }
+    }
+
+    [Storable]
+    private OrchestratedAlgorithmNode assistedOptimizerNode;
+    private OrchestratedAlgorithmNode AssistedOptimizerNode {
+      get { return assistedOptimizerNode; }
+      set {
+        if (assistedOptimizerNode != null)
+          throw new InvalidOperationException("AssistedOptimizerNode has already been initialized.");
+        assistedOptimizerNode = value;
+      }
+    }
+    #endregion
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private SurrogateModelingNetwork(bool deserializing) : base(deserializing) { }
+    private SurrogateModelingNetwork(SurrogateModelingNetwork original, Cloner cloner) : base(original, cloner) { }
+    public SurrogateModelingNetwork() : this("Surrogate Modeling Network") { }
+    public SurrogateModelingNetwork(string name) : this(name, "") { }
+    public SurrogateModelingNetwork(string name, string description) : base(name, description) {
+      ConfigureOrchestrator();
+      ConfigureFullEvaluator();
+      ConfigurePointGenerator();
+      ConfigureModelBuilder();
+      ConfigureAssistedOptimizer();
+
+      Orchestrator.Prepare();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SurrogateModelingNetwork(this, cloner);
+    }
+    #endregion
+
+    private void ConfigureOrchestrator() {
+      Orchestrator = new SurrogateModelingOrchestrator();
+      Nodes.Add(Orchestrator);
+    }
+
+    private void ConfigureFullEvaluator() {
+      FullEvaluatorNode = new FullEvaluatorNode();
+      Nodes.Add(FullEvaluatorNode);
+
+      Orchestrator.FullEvaluatorOrchPort.ConnectedPort = FullEvaluatorNode.OrchestrationPort;
+      Orchestrator.FullEvaluatorExploitationEvalPort.ConnectedPort = FullEvaluatorNode.ExploitationFullEvalRequestPort;
+      Orchestrator.FullEvaluatorExplorationEvalPort.ConnectedPort = FullEvaluatorNode.ExplorationFullEvalRequestPort;
+      Orchestrator.FullEvaluatorUpdatePort.ConnectedPort = FullEvaluatorNode.UpdateRegressionSolutionPort;
+      FullEvaluatorNode.EvaluationPort.CloneParametersFromPort(Orchestrator.FullEvaluatorEvalPort);
+      FullEvaluatorNode.EvaluationPort.ConnectedPort = Orchestrator.FullEvaluatorEvalPort;
+    }
+
+    private void ConfigurePointGenerator() {
+      PointGeneratorNode = new OrchestratedAlgorithmNode("Point Generator") {
+        Algorithm = new RandomSearchAlgorithm {
+          MaximumEvaluatedSolutions = int.MaxValue
+        }
+      };
+      Nodes.Add(PointGeneratorNode);
+
+      Orchestrator.PointGeneratorOrchPort.ConnectedPort = PointGeneratorNode.OrchestrationPort;
+      PointGeneratorNode.EvaluationPort.CloneParametersFromPort(Orchestrator.PointGeneratorEvalPort);
+      PointGeneratorNode.EvaluationPort.ConnectedPort = Orchestrator.PointGeneratorEvalPort;
+    }
+
+    private void ConfigureModelBuilder() {
+      ModelBuilderNode = new OrchestratedAlgorithmNode("Model Builder") {
+        Algorithm = new GaussianProcessRegression()
+      };
+      var updatePort = new ConfigurationPort("Update ProblemData") {
+        Parameters = {
+          new PortParameter<IRegressionProblemData>("ProblemData") {
+            Type = PortParameterType.Input
+          }
+        }
+      };
+      ModelBuilderNode.Ports.Add(updatePort);
+      Nodes.Add(ModelBuilderNode);
+
+      Orchestrator.ModelBuilderOrchPort.ConnectedPort = ModelBuilderNode.OrchestrationPort;
+      Orchestrator.ModelBuilderUpdatePort.ConnectedPort = updatePort;
+      ModelBuilderNode.EvaluationPort.CloneParametersFromPort(Orchestrator.ModelBuilderEvalPort);
+      ModelBuilderNode.EvaluationPort.ConnectedPort = Orchestrator.ModelBuilderEvalPort;
+    }
+
+    private void ConfigureAssistedOptimizer() {
+      AssistedOptimizerNode = new OrchestratedAlgorithmNode("Assisted Optimizer") {
+        Algorithm = new AlpsGeneticAlgorithm {
+          MaximumGenerations = 250,
+          ReevaluteElites = true
+        }
+      };
+      var updatePort = new ConfigurationPort("Update RegressionSolution") {
+        Parameters = {
+          new PortParameter<IRegressionSolution>("RegressionSolution") {
+            Type = PortParameterType.Input
+          }
+        }
+      };
+      AssistedOptimizerNode.Ports.Add(updatePort);
+      Nodes.Add(AssistedOptimizerNode);
+
+      Orchestrator.AssistedOptimizerOrchPort.ConnectedPort = AssistedOptimizerNode.OrchestrationPort;
+      Orchestrator.AssistedOptimizerUpdatePort.ConnectedPort = updatePort;
+      AssistedOptimizerNode.EvaluationPort.CloneParametersFromPort(Orchestrator.AssistedOptimizerEvalPort);
+      AssistedOptimizerNode.EvaluationPort.ConnectedPort = Orchestrator.AssistedOptimizerEvalPort;
+    }
+  }
+}
Index: branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingOrchestrator.cs
===================================================================
--- branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingOrchestrator.cs	(revision 15896)
+++ branches/2205_OptimizationNetworks/HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling/3.3/SurrogateModelingOrchestrator.cs	(revision 15896)
@@ -0,0 +1,614 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Core.Networks;
+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.Problems.TestFunctions;
+
+namespace HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling {
+  [Item("Surrogate Modeling Orchestrator", "")]
+  [StorableClass]
+  public sealed class SurrogateModelingOrchestrator : OrchestratorNode {
+    private readonly object aoProblemSync = new object();
+    private readonly object mbProblemSync = new object();
+    private readonly object bestSolutionSync = new object();
+    private readonly ManualResetEventSlim mbSignal = new ManualResetEventSlim(false);
+    private readonly ManualResetEventSlim aoSignal = new ManualResetEventSlim(false);
+    private CancellationTokenSource cts;
+
+    [Storable]
+    public ExecutionState ExecutionState { get; set; }
+
+    [Storable]
+    public IRegressionProblem CurrentModelBuilderProblem { get; set; }
+    [Storable]
+    public AssistedOptimizerProblem CurrentAssistedOptimizerProblem { get; set; }
+    [Storable]
+    public IScope EstimatedBestSolution { get; set; }
+
+    #region Port Names
+    private const string FullEvaluatorOrchPortName = "Full Evaluator Orchestration";
+    private const string FullEvaluatorEvalPortName = "Full Evaluator Evaluation";
+    private const string FullEvaluatorExploitationEvalPortName = "Full Evaluator Exploitation";
+    private const string FullEvaluatorExplorationEvalPortName = "Full Evaluator Exploration";
+    private const string FullEvaluatorUpdatePortName = "Full Evaluator Update";
+    private const string PointGeneratorOrchPortName = "Point Generator Orchestration";
+    private const string PointGeneratorEvalPortName = "Point Generator Evaluation";
+    private const string ModelBuilderOrchPortName = "Model Builder Orchestration";
+    private const string ModelBuilderEvalPortName = "Model Builder Evaluation";
+    private const string ModelBuilderUpdatePortName = "Model Builder Update";
+    private const string AssistedOptimizerOrchPortName = "Assisted Optimizer Orchestration";
+    private const string AssistedOptimizerEvalPortName = "Assisted Optimizer Evaluation";
+    private const string AssistedOptimizerUpdatePortName = "Assisted Optimizer Update";
+    #endregion
+
+    #region Ports
+    public IMessagePort FullEvaluatorOrchPort { get { return (IMessagePort)Ports[FullEvaluatorOrchPortName]; } }
+    public IMessagePort FullEvaluatorEvalPort { get { return (IMessagePort)Ports[FullEvaluatorEvalPortName]; } }
+    public IMessagePort FullEvaluatorExploitationEvalPort { get { return (IMessagePort)Ports[FullEvaluatorExploitationEvalPortName]; } }
+    public IMessagePort FullEvaluatorExplorationEvalPort { get { return (IMessagePort)Ports[FullEvaluatorExplorationEvalPortName]; } }
+    public IMessagePort FullEvaluatorUpdatePort { get { return (IMessagePort)Ports[FullEvaluatorUpdatePortName]; } }
+    public IMessagePort PointGeneratorOrchPort { get { return (IMessagePort)Ports[PointGeneratorOrchPortName]; } }
+    public IMessagePort PointGeneratorEvalPort { get { return (IMessagePort)Ports[PointGeneratorEvalPortName]; } }
+    public IMessagePort ModelBuilderOrchPort { get { return (IMessagePort)Ports[ModelBuilderOrchPortName]; } }
+    public IMessagePort ModelBuilderEvalPort { get { return (IMessagePort)Ports[ModelBuilderEvalPortName]; } }
+    public IMessagePort ModelBuilderUpdatePort { get { return (IMessagePort)Ports[ModelBuilderUpdatePortName]; } }
+    public IMessagePort AssistedOptimizerOrchPort { get { return (IMessagePort)Ports[AssistedOptimizerOrchPortName]; } }
+    public IMessagePort AssistedOptimizerEvalPort { get { return (IMessagePort)Ports[AssistedOptimizerEvalPortName]; } }
+    public IMessagePort AssistedOptimizerUpdatePort { get { return (IMessagePort)Ports[AssistedOptimizerUpdatePortName]; } }
+    #endregion
+
+    #region Parameter Names
+    private const string TestFunctionProblemParameterName = "TestFunctionProblem";
+    private const string PointGeneratorProblemParameterName = "PointGeneratorProblem";
+    private const string ModelBuilderRegressionProblemParameterName = "ModelBuilderRegressionProblem";
+    private const string AssistedOptimizerProblemParameterName = "AssistedOptimizerProblem";
+    private const string MinPointsParameterName = "MinPoints";
+    private const string MaxPointsParameterName = "MaxPoints";
+    private const string MinModelQualityParameterName = "MinModelQuality";
+    #endregion
+
+    #region Parameters
+    private IValueParameter<SingleObjectiveTestFunctionProblem> TestFunctionProblemParameter {
+      get { return (IValueParameter<SingleObjectiveTestFunctionProblem>)Parameters[TestFunctionProblemParameterName]; }
+    }
+
+    private IValueParameter<PointGeneratorProblem> PointGeneratorProblemParameter {
+      get { return (IValueParameter<PointGeneratorProblem>)Parameters[PointGeneratorProblemParameterName]; }
+    }
+
+    private IValueParameter<IRegressionProblem> ModelBuilderRegressionProblemParameter {
+      get { return (IValueParameter<IRegressionProblem>)Parameters[ModelBuilderRegressionProblemParameterName]; }
+    }
+
+    private IValueParameter<AssistedOptimizerProblem> AssistedOptimizerProblemParameter {
+      get { return (IValueParameter<AssistedOptimizerProblem>)Parameters[AssistedOptimizerProblemParameterName]; }
+    }
+
+    private IValueParameter<IntValue> MinPointsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MinPointsParameterName]; }
+    }
+
+    private IValueParameter<IntValue> MaxPointsParameter {
+      get { return (IValueParameter<IntValue>)Parameters[MaxPointsParameterName]; }
+    }
+
+    private IValueParameter<DoubleValue> MinModelQualityParameter {
+      get { return (IValueParameter<DoubleValue>)Parameters[MinModelQualityParameterName]; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private SingleObjectiveTestFunctionProblem TestFunctionProblem {
+      get { return TestFunctionProblemParameter.Value; }
+      set { TestFunctionProblemParameter.Value = value; }
+    }
+
+    private PointGeneratorProblem PointGeneratorProblem {
+      get { return PointGeneratorProblemParameter.Value; }
+      set { PointGeneratorProblemParameter.Value = value; }
+    }
+
+    private IRegressionProblem ModelBuilderRegressionProblem {
+      get { return ModelBuilderRegressionProblemParameter.Value; }
+      set { ModelBuilderRegressionProblemParameter.Value = value; }
+    }
+
+    private AssistedOptimizerProblem AssistedOptimizerProblem {
+      get { return AssistedOptimizerProblemParameter.Value; }
+      set { AssistedOptimizerProblemParameter.Value = value; }
+    }
+
+    private IntValue MinPoints {
+      get { return MinPointsParameter.Value; }
+      set { MinPointsParameter.Value = value; }
+    }
+
+    private IntValue MaxPoints {
+      get { return MaxPointsParameter.Value; }
+      set { MaxPointsParameter.Value = value; }
+    }
+
+    private DoubleValue MinModelQuality {
+      get { return MinModelQualityParameter.Value; }
+      set { MinModelQualityParameter.Value = value; }
+    }
+    #endregion
+
+    #region Constructors & Cloning
+    [StorableConstructor]
+    private SurrogateModelingOrchestrator(bool deserializing) : base(deserializing) { }
+    private SurrogateModelingOrchestrator(SurrogateModelingOrchestrator original, Cloner cloner) : base(original, cloner) {
+      RegisterPortEvents();
+    }
+    public SurrogateModelingOrchestrator() : this("Surrogate Modeling Orchestrator") { }
+    public SurrogateModelingOrchestrator(string name) : this(name, "") { }
+    public SurrogateModelingOrchestrator(string name, string description) : base(name, description) {
+      AddParameters();
+
+      AddFullEvaluatorPorts();
+      AddPointGeneratorPorts();
+      AddModelBuilderPorts();
+      AddAssistedOptimizerPorts();
+
+      RegisterPortEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SurrogateModelingOrchestrator(this, cloner);
+    }
+    #endregion
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterPortEvents();
+    }
+
+    public override void Prepare(bool clearRuns = false) {
+      if (ExecutionState == ExecutionState.Started)
+        throw new InvalidOperationException("Prepare not allowed in execution state " + ExecutionState);
+
+      ExecutionState = ExecutionState.Prepared;
+      EstimatedBestSolution = null;
+      Results.Clear();
+
+      var orchMsg = OrchestrationMessage.Prepare;
+      if (clearRuns) orchMsg |= OrchestrationMessage.ClearRuns;
+
+      var tfProblem = (SingleObjectiveTestFunctionProblem)TestFunctionProblem.Clone();
+      var pgProblem = (PointGeneratorProblem)PointGeneratorProblem.Clone();
+      var mbProblem = (IRegressionProblem)ModelBuilderRegressionProblem.Clone();
+      var aoProblem = (AssistedOptimizerProblem)AssistedOptimizerProblem.Clone();
+
+      pgProblem.Encoding.Bounds = tfProblem.Bounds;
+      pgProblem.Encoding.Length = tfProblem.ProblemSize.Value;
+      pgProblem.NotifyEvaluation = (point, quality) => {
+        var evalPort = (IMessagePort)PointGeneratorOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
+        var evalMsg = evalPort.PrepareMessage();
+        evalMsg["RealVector"] = point;
+        evalMsg["Quality"] = new DoubleValue(quality);
+        evalPort.SendMessage(evalMsg);
+      };
+
+      var fullEvaluatorNode = (FullEvaluatorNode)FullEvaluatorOrchPort.ConnectedPort.Parent;
+      fullEvaluatorNode.Algorithm.NotifyEvaluation = (point, quality) => {
+        var evalPort = (IMessagePort)fullEvaluatorNode.Ports["EvaluationPort"];
+        var evalMsg = evalPort.PrepareMessage();
+        evalMsg["RealVector"] = point;
+        evalMsg["Quality"] = new DoubleValue(quality);
+        evalPort.SendMessage(evalMsg);
+      };
+
+      var variableNames = Enumerable.Range(0, tfProblem.ProblemSize.Value).Select(x => x.ToString("X00#")).Concat(new[] { "TARGET" });
+      var variableValues = variableNames.Select(x => new List<double>());
+      var modifiableDataset = new ModifiableDataset(variableNames, variableValues);
+      mbProblem.ProblemData = new RegressionProblemData(modifiableDataset, variableNames.Except(new[] { "TARGET" }), variableNames.Last());
+
+      aoProblem.Encoding.Bounds = tfProblem.Bounds;
+      aoProblem.Encoding.Length = tfProblem.ProblemSize.Value;
+      aoProblem.NotifyEvaluation = (point, quality) => {
+        var evalPort = (IMessagePort)AssistedOptimizerOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
+        var evalMsg = evalPort.PrepareMessage();
+        evalMsg["RealVector"] = point;
+        evalMsg["Quality"] = new DoubleValue(quality);
+        evalPort.SendMessage(evalMsg);
+      };
+
+      CurrentModelBuilderProblem = mbProblem;
+      CurrentAssistedOptimizerProblem = aoProblem;
+
+      var tasks = new[] {
+        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, orchMsg, tfProblem),
+        SendOrchestrationMessageAsync(PointGeneratorOrchPort, orchMsg, pgProblem),
+        SendOrchestrationMessageAsync(ModelBuilderOrchPort, orchMsg, mbProblem),
+        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, orchMsg, aoProblem)
+      };
+
+      Task.WhenAll(tasks);
+    }
+
+    public override void Start() {
+      if (ExecutionState != ExecutionState.Prepared)
+        throw new InvalidOperationException("Start not allowed in execution state " + ExecutionState);
+
+      ExecutionState = ExecutionState.Started;
+
+      bool mbReady = CurrentModelBuilderProblem.ProblemData.Dataset.Rows >= MinPoints.Value;
+      if (mbReady) mbSignal.Set();
+      else mbSignal.Reset();
+
+      bool aoReady = CurrentAssistedOptimizerProblem.RegressionSolution != null;
+      if (aoReady) aoSignal.Set();
+      else aoSignal.Reset();
+
+      if (cts != null) {
+        cts.Cancel();
+        cts.Dispose();
+      }
+      cts = new CancellationTokenSource();
+
+      var tasks = new[] {
+        StartFullEvaluatorAsync(),
+        StartPointGeneratorMonitoringAsync(),
+        StartModelBuilderMonitoringAsync(),
+        StartAssistedOptimizerMonitoringAsync()
+      };
+
+      Task.WhenAll(tasks);
+    }
+
+    public override void Pause() {
+      if (ExecutionState != ExecutionState.Started)
+        throw new InvalidOperationException("Pause not allowed in execution state " + ExecutionState);
+
+      ExecutionState = ExecutionState.Paused;
+
+      cts.Cancel();
+
+      var tasks = new[] {
+        SendOrchestrationMessageAsync(PointGeneratorOrchPort, OrchestrationMessage.Pause),
+        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Pause),
+        SendOrchestrationMessageAsync(ModelBuilderOrchPort, OrchestrationMessage.Pause),
+        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, OrchestrationMessage.Pause)
+      };
+
+      Task.WhenAll(tasks);
+    }
+
+    public override void Stop() {
+      if (ExecutionState != ExecutionState.Started && ExecutionState != ExecutionState.Paused)
+        throw new InvalidOperationException("Stop not allowed in execution state " + ExecutionState);
+
+      ExecutionState = ExecutionState.Stopped;
+
+      cts.Cancel();
+
+      var tasks = new[] {
+        SendOrchestrationMessageAsync(PointGeneratorOrchPort, OrchestrationMessage.Stop),
+        SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Stop),
+        SendOrchestrationMessageAsync(ModelBuilderOrchPort, OrchestrationMessage.Stop),
+        SendOrchestrationMessageAsync(AssistedOptimizerOrchPort, OrchestrationMessage.Stop)
+      };
+
+      Task.WhenAll(tasks);
+    }
+
+    #region Helpers
+    private void AddParameters() {
+      var tfProblem = new SingleObjectiveTestFunctionProblem();
+      var pgProblem = new PointGeneratorProblem();
+      var mbProblem = new RegressionProblem();
+      var aoProblem = new AssistedOptimizerProblem();
+
+      var variableNames = "DUMMY".ToEnumerable();
+      var variableValues = new List<double>().ToEnumerable();
+      var modifiableDataset = new ModifiableDataset(variableNames, variableValues);
+      mbProblem.ProblemData = new RegressionProblemData(modifiableDataset, variableNames, variableNames.Last());
+
+      Parameters.Add(new ValueParameter<SingleObjectiveTestFunctionProblem>(TestFunctionProblemParameterName, tfProblem));
+      Parameters.Add(new ValueParameter<PointGeneratorProblem>(PointGeneratorProblemParameterName, pgProblem));
+      Parameters.Add(new ValueParameter<IRegressionProblem>(ModelBuilderRegressionProblemParameterName, mbProblem));
+      Parameters.Add(new ValueParameter<AssistedOptimizerProblem>(AssistedOptimizerProblemParameterName, aoProblem));
+      Parameters.Add(new ValueParameter<IntValue>(MinPointsParameterName, new IntValue(1)));
+      Parameters.Add(new ValueParameter<IntValue>(MaxPointsParameterName, new IntValue(int.MaxValue)));
+      Parameters.Add(new ValueParameter<DoubleValue>(MinModelQualityParameterName, new DoubleValue(0.95)));
+    }
+
+    private void AddFullEvaluatorPorts() {
+      var orchPort = CreateOrchestrationPort<SingleObjectiveTestFunctionProblem>(FullEvaluatorOrchPortName);
+      Ports.Add(orchPort);
+
+      var evalPort = CreateEvaluationPort<RealVector>(FullEvaluatorEvalPortName, "RealVector", "Quality");
+      Ports.Add(evalPort);
+
+      var exploitationPort = CreateEvaluationPort<RealVector>(FullEvaluatorExploitationEvalPortName, "RealVector", "Quality");
+      Ports.Add(exploitationPort);
+
+      var explorationPort = CreateEvaluationPort<RealVector>(FullEvaluatorExplorationEvalPortName, "RealVector", "Quality");
+      Ports.Add(explorationPort);
+
+      var updatePort = new ConfigurationPort(FullEvaluatorUpdatePortName) {
+        Parameters = {
+          new PortParameter<IRegressionSolution>("RegressionSolution") {
+            Type = PortParameterType.Output
+          }
+        }
+      };
+      Ports.Add(updatePort);
+    }
+
+    private void AddPointGeneratorPorts() {
+      var orchPort = CreateOrchestrationPort<PointGeneratorProblem>(PointGeneratorOrchPortName);
+      Ports.Add(orchPort);
+
+      var evalPort = CreateEvaluationPort<RealVector>(PointGeneratorEvalPortName, "RealVector", "Quality");
+      Ports.Add(evalPort);
+    }
+
+    private void AddModelBuilderPorts() {
+      var orchPort = CreateOrchestrationPort<IRegressionProblem>(ModelBuilderOrchPortName);
+      Ports.Add(orchPort);
+
+      var evalPort = CreateEvaluationPort<IRegressionSolution>(ModelBuilderEvalPortName, "RegressionSolution", "Quality");
+      Ports.Add(evalPort);
+
+      var updatePort = new ConfigurationPort(ModelBuilderUpdatePortName) {
+        Parameters = {
+          new PortParameter<IRegressionProblemData>("ProblemData") {
+            Type = PortParameterType.Output
+          }
+        }
+      };
+      Ports.Add(updatePort);
+    }
+
+    private void AddAssistedOptimizerPorts() {
+      var orchPort = CreateOrchestrationPort<AssistedOptimizerProblem>(AssistedOptimizerOrchPortName);
+      Ports.Add(orchPort);
+
+      var evalPort = CreateEvaluationPort<RealVector>(AssistedOptimizerEvalPortName, "RealVector", "Quality");
+      Ports.Add(evalPort);
+
+      var updatePort = new ConfigurationPort(AssistedOptimizerUpdatePortName) {
+        Parameters = {
+          new PortParameter<IRegressionSolution>("RegressionSolution") {
+            Type = PortParameterType.Output
+          }
+        }
+      };
+      Ports.Add(updatePort);
+    }
+
+    private void RegisterPortEvents() {
+      PointGeneratorEvalPort.MessageReceived += PointGeneratorEvalPort_MessageReceived;
+      ModelBuilderEvalPort.MessageReceived += ModelBuilderEvalPort_MessageReceived;
+      AssistedOptimizerEvalPort.MessageReceived += AssistedOptimizerEvalPort_MessageReceived;
+      FullEvaluatorEvalPort.MessageReceived += FullEvaluatorEvalPort_MessageReceived;
+    }
+
+    private IMessage SendOrchestrationMessage(IMessagePort orchPort, OrchestrationMessage message, IProblem problem = null) {
+      var msg = orchPort.PrepareMessage();
+
+      msg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(message);
+      if (problem != null) msg["Problem"] = problem;
+
+      orchPort.SendMessage(msg);
+
+      return msg;
+    }
+
+    private async Task<IMessage> SendOrchestrationMessageAsync(IMessagePort orchPort, OrchestrationMessage message, IProblem problem = null) {
+      var msg = orchPort.PrepareMessage();
+
+      msg["OrchestrationMessage"] = new EnumValue<OrchestrationMessage>(message);
+      if (problem != null) msg["Problem"] = problem;
+
+      await orchPort.SendMessageAsync(msg);
+
+      return msg;
+    }
+
+    private Task StartFullEvaluatorAsync() {
+      return SendOrchestrationMessageAsync(FullEvaluatorOrchPort, OrchestrationMessage.Start);
+    }
+
+    private Task StartPointGeneratorMonitoringAsync() {
+      return AsyncHelper.DoAsync(ct => {
+        var startOrchMsg = OrchestrationMessage.Start;
+        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
+
+        while (!ct.IsCancellationRequested) {
+          SendOrchestrationMessage(PointGeneratorOrchPort, prepareOrchMsg);
+          SendOrchestrationMessage(PointGeneratorOrchPort, startOrchMsg);
+        }
+      }, cts.Token);
+    }
+
+    private Task StartModelBuilderMonitoringAsync() {
+      return AsyncHelper.DoAsync(ct => {
+        IMessage message;
+        var startOrchMsg = OrchestrationMessage.Start;
+        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
+
+        mbSignal.Wait(cts.Token);
+
+        IRegressionProblem mbProblem;
+
+        while (!ct.IsCancellationRequested) {
+          lock (mbProblemSync) mbProblem = (IRegressionProblem)CurrentModelBuilderProblem.Clone();
+          SendOrchestrationMessage(ModelBuilderOrchPort, prepareOrchMsg, mbProblem);
+
+          message = SendOrchestrationMessage(ModelBuilderOrchPort, startOrchMsg);
+
+          var results = (ResultCollection)message["Results"];
+          var bestSolution = results.Select(x => x.Value).OfType<IRegressionSolution>().SingleOrDefault();
+          var clonedSolution = (IRegressionSolution)bestSolution.Clone();
+
+          var evalMsg = ModelBuilderEvalPort.PrepareMessage();
+          evalMsg["RegressionSolution"] = clonedSolution;
+          evalMsg["Quality"] = new DoubleValue(clonedSolution.TrainingRSquared);
+          ModelBuilderEvalPort.ReceiveMessage(evalMsg, ct);
+        }
+      }, cts.Token);
+    }
+
+    private Task StartAssistedOptimizerMonitoringAsync() {
+      return AsyncHelper.DoAsync(ct => {
+        IMessage message;
+        var prepareOrchMsg = OrchestrationMessage.Prepare | OrchestrationMessage.ClearRuns;
+        var startOrchMsg = OrchestrationMessage.Start;
+
+        aoSignal.Wait(cts.Token);
+
+        AssistedOptimizerProblem aoProblem;
+
+        while (!ct.IsCancellationRequested) {
+          lock (aoProblemSync) aoProblem = (AssistedOptimizerProblem)CurrentAssistedOptimizerProblem.Clone();
+          aoProblem.NotifyEvaluation = (point, quality) => {
+            var evalPort = (IMessagePort)AssistedOptimizerOrchPort.ConnectedPort.Parent.Ports["EvaluationPort"];
+            var msg = evalPort.PrepareMessage();
+            msg["RealVector"] = point;
+            msg["Quality"] = new DoubleValue(quality);
+            evalPort.SendMessage(msg);
+          };
+          SendOrchestrationMessage(AssistedOptimizerOrchPort, prepareOrchMsg, aoProblem);
+
+          message = SendOrchestrationMessage(AssistedOptimizerOrchPort, startOrchMsg);
+
+          var results = (ResultCollection)message["Results"];
+          var bestSolution = (RealVector)results["BestSolution"].Value.Clone();
+          var bestQuality = (DoubleValue)results["BestQuality"].Value.Clone();
+
+          var evalMsg = AssistedOptimizerEvalPort.PrepareMessage();
+          evalMsg["RealVector"] = bestSolution;
+          evalMsg["Quality"] = bestQuality;
+          AssistedOptimizerEvalPort.ReceiveMessage(evalMsg, ct);
+        }
+      }, cts.Token);
+    }
+
+    private void AddRowToDataset(IRegressionProblem problem, IEnumerable<object> row) {
+      var problemData = problem.ProblemData;
+      var dataset = problemData.Dataset;
+      var r = row.ToArray();
+
+      var modifiableDataset = dataset as ModifiableDataset ?? ((Dataset)dataset).ToModifiable();
+      if (modifiableDataset.Rows > MaxPoints.Value) {
+        var targetValues = modifiableDataset.GetDoubleValues(problemData.TargetVariable).ToList();
+        var maxTargetValue = targetValues.Max();
+        if (maxTargetValue > (double)r.Last()) {
+          int index = targetValues.IndexOf(maxTargetValue);
+          modifiableDataset.ReplaceRow(index, row);
+        }
+      } else modifiableDataset.AddRow(row);
+
+      problemData = new RegressionProblemData(modifiableDataset, problemData.AllowedInputVariables, problemData.TargetVariable);
+      problemData.TrainingPartition.End = modifiableDataset.Rows;
+      problemData.TestPartition.Start = modifiableDataset.Rows;
+
+      problem.ProblemData = problemData;
+    }
+
+
+    private static bool IsBetter(double oldValue, double newValue, bool maximization) {
+      return maximization ? newValue > oldValue : newValue < oldValue;
+    }
+    #endregion
+
+    #region Event Handlers
+    private void PointGeneratorEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      // just forward message to full evaluator
+      FullEvaluatorExplorationEvalPort.SendMessage(evalMsg);
+    }
+
+    private void FullEvaluatorEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      var realVector = (RealVector)evalMsg["RealVector"];
+      var quality = (DoubleValue)evalMsg["Quality"];
+
+      if (realVector.Length == 0 && double.IsNaN(quality.Value)) {
+        Stop();
+        return;
+      }
+
+      var sample = realVector.ToList();
+      sample.Add(quality.Value);
+      var row = sample.Select(x => (object)x).ToList();
+
+      lock (mbProblemSync) {
+        AddRowToDataset(CurrentModelBuilderProblem, row);
+        if (!mbSignal.IsSet && CurrentModelBuilderProblem.ProblemData.Dataset.Rows >= MinPoints.Value) mbSignal.Set();
+      }
+
+      //lock (aoProblemSync) {
+      //  if (CurrentAssistedOptimizerProblem.RegressionSolution != null)
+      //    CurrentAssistedOptimizerProblem.RegressionSolution.ProblemData = CurrentModelBuilderProblem.ProblemData;
+      //}
+    }
+
+    private void ModelBuilderEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      var solution = (IRegressionSolution)evalMsg["RegressionSolution"];
+      var quality = (DoubleValue)evalMsg["Quality"];
+
+      if (solution.TrainingRSquared < MinModelQuality.Value) return;
+
+      lock (aoProblemSync) {
+        CurrentAssistedOptimizerProblem.RegressionSolution = solution;
+        if (!aoSignal.IsSet) aoSignal.Set();
+        else {
+          if (AssistedOptimizerUpdatePort.ConnectedPort != null) {
+            var updateMsg = AssistedOptimizerUpdatePort.PrepareMessage();
+            updateMsg["RegressionSolution"] = (IRegressionSolution)CurrentAssistedOptimizerProblem.RegressionSolution.Clone();
+            AssistedOptimizerUpdatePort.SendMessage(updateMsg);
+          }
+          if (FullEvaluatorUpdatePort.ConnectedPort != null) {
+            var updateMsg = FullEvaluatorUpdatePort.PrepareMessage();
+            updateMsg["RegressionSolution"] = (IRegressionSolution)CurrentAssistedOptimizerProblem.RegressionSolution.Clone();
+            FullEvaluatorUpdatePort.SendMessage(updateMsg);
+          }
+        }
+      }
+    }
+
+    private void AssistedOptimizerEvalPort_MessageReceived(object sender, EventArgs<IMessage, CancellationToken> e) {
+      var evalMsg = e.Value;
+      // just forward message to full evaluator
+      FullEvaluatorExploitationEvalPort.SendMessage(evalMsg);
+
+      var realVector = (RealVector)evalMsg["RealVector"];
+      var quality = (DoubleValue)evalMsg["Quality"];
+
+      lock (bestSolutionSync) {
+        if (EstimatedBestSolution == null) {
+          EstimatedBestSolution = new Scope("BestSolution") {
+            Variables = {
+              new Variable("RealVector", realVector),
+              new Variable("Quality", quality)
+            }
+          };
+        } else {
+          var oldRealVectorVariable = EstimatedBestSolution.Variables["RealVector"];
+          var oldQualityVariable = EstimatedBestSolution.Variables["Quality"];
+
+          var oldQuality = (DoubleValue)oldQualityVariable.Value;
+          if (IsBetter(oldQuality.Value, quality.Value, false)) {
+            oldRealVectorVariable.Value = realVector;
+            oldQualityVariable.Value = quality;
+          }
+        }
+      }
+    }
+    #endregion
+  }
+}
Index: branches/2205_OptimizationNetworks/SM-Networks.sln
===================================================================
--- branches/2205_OptimizationNetworks/SM-Networks.sln	(revision 15896)
+++ branches/2205_OptimizationNetworks/SM-Networks.sln	(revision 15896)
@@ -0,0 +1,51 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27004.2009
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3", "HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling\3.3\HeuristicLab.Networks.IntegratedOptimization.SurrogateModeling-3.3.csproj", "{12819229-8D69-44A3-9EF4-5A95D833F205}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Networks.IntegratedOptimization-3.3", "HeuristicLab.Networks.IntegratedOptimization\3.3\HeuristicLab.Networks.IntegratedOptimization-3.3.csproj", "{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|Any CPU = Release|Any CPU
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|x64.ActiveCfg = Debug|x64
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|x64.Build.0 = Debug|x64
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|x86.ActiveCfg = Debug|x86
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Debug|x86.Build.0 = Debug|x86
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|Any CPU.Build.0 = Release|Any CPU
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|x64.ActiveCfg = Release|x64
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|x64.Build.0 = Release|x64
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|x86.ActiveCfg = Release|x86
+		{12819229-8D69-44A3-9EF4-5A95D833F205}.Release|x86.Build.0 = Release|x86
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|x64.ActiveCfg = Debug|x64
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|x64.Build.0 = Debug|x64
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|x86.ActiveCfg = Debug|x86
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Debug|x86.Build.0 = Debug|x86
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|Any CPU.Build.0 = Release|Any CPU
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|x64.ActiveCfg = Release|x64
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|x64.Build.0 = Release|x64
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|x86.ActiveCfg = Release|x86
+		{B6263D3E-DCAF-42B0-A440-3DEEF1FF0429}.Release|x86.Build.0 = Release|x86
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {C405A866-F2CF-4C9F-8FFF-9741B2BCDBD4}
+	EndGlobalSection
+EndGlobal
