Index: /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/HeuristicLab.Algorithms.GeneticAlgorithm-3.3.csproj
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/HeuristicLab.Algorithms.GeneticAlgorithm-3.3.csproj	(revision 15624)
+++ /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/HeuristicLab.Algorithms.GeneticAlgorithm-3.3.csproj	(revision 15625)
@@ -115,4 +115,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Model2\SolutionScope.cs" />
+    <Compile Include="Model2\GeneticAlgorithm.cs" />
     <Compile Include="GeneticAlgorithm.cs" />
     <Compile Include="GeneticAlgorithmMainLoop.cs" />
Index: /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/GeneticAlgorithm.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/GeneticAlgorithm.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/GeneticAlgorithm.cs	(revision 15625)
@@ -0,0 +1,411 @@
+#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.Model2;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.GeneticAlgorithm.Model2 {
+  /// <summary>
+  /// A genetic algorithm.
+  /// </summary>
+  [Item("Genetic Algorithm (GA) v2", "A genetic algorithm.")]
+  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 100)]
+  [StorableClass]
+  public sealed class GeneticAlgorithm : StochasticAlgorithm<PopulationContext<SolutionScope>> {
+    public override bool SupportsPause {
+      get { return true; }
+    }
+
+    #region Problem Properties
+    public override Type ProblemType {
+      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
+    }
+    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
+      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+    #endregion
+
+    #region Parameter Properties
+    private FixedValueParameter<IntValue> PopulationSizeParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["PopulationSize"]; }
+    }
+    public IConstrainedValueParameter<ISelector> SelectorParameter {
+      get { return (IConstrainedValueParameter<ISelector>)Parameters["Selector"]; }
+    }
+    public IConstrainedValueParameter<ICrossover> CrossoverParameter {
+      get { return (IConstrainedValueParameter<ICrossover>)Parameters["Crossover"]; }
+    }
+    private FixedValueParameter<PercentValue> MutationProbabilityParameter {
+      get { return (FixedValueParameter<PercentValue>)Parameters["MutationProbability"]; }
+    }
+    public IConstrainedValueParameter<IManipulator> MutatorParameter {
+      get { return (IConstrainedValueParameter<IManipulator>)Parameters["Mutator"]; }
+    }
+    private FixedValueParameter<IntValue> ElitesParameter {
+      get { return (FixedValueParameter<IntValue>)Parameters["Elites"]; }
+    }
+    private IFixedValueParameter<BoolValue> ReevaluateElitesParameter {
+      get { return (IFixedValueParameter<BoolValue>)Parameters["ReevaluateElites"]; }
+    }
+    #endregion
+
+    #region Properties
+    public int PopulationSize {
+      get { return PopulationSizeParameter.Value.Value; }
+      set { PopulationSizeParameter.Value.Value = value; }
+    }
+    public ISelector Selector {
+      get { return SelectorParameter.Value; }
+      set { SelectorParameter.Value = value; }
+    }
+    public ICrossover Crossover {
+      get { return CrossoverParameter.Value; }
+      set { CrossoverParameter.Value = value; }
+    }
+    public double MutationProbability {
+      get { return MutationProbabilityParameter.Value.Value; }
+      set { MutationProbabilityParameter.Value.Value = value; }
+    }
+    public IManipulator Mutator {
+      get { return MutatorParameter.Value; }
+      set { MutatorParameter.Value = value; }
+    }
+    public int Elites {
+      get { return ElitesParameter.Value.Value; }
+      set { ElitesParameter.Value.Value = value; }
+    }
+    public bool ReevaluteElites {
+      get { return ReevaluateElitesParameter.Value.Value; }
+      set { ReevaluateElitesParameter.Value.Value = value; }
+    }
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+    #endregion
+
+    public GeneticAlgorithm()
+      : base() {
+      Parameters.Add(new FixedValueParameter<IntValue>("PopulationSize", "The size of the population of solutions.", new IntValue(100)));
+      Parameters.Add(new ConstrainedValueParameter<ISelector>("Selector", "The operator used to select solutions for reproduction."));
+      Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to cross solutions."));
+      Parameters.Add(new FixedValueParameter<PercentValue>("MutationProbability", "The probability that the mutation operator is applied on a solution.", new PercentValue(0.05)));
+      Parameters.Add(new ConstrainedValueParameter<IManipulator>("Mutator", "The operator used to mutate solutions."));
+      Parameters.Add(new FixedValueParameter<IntValue>("Elites", "The numer of elite solutions which are kept in each generation.", new IntValue(1)));
+      Parameters.Add(new FixedValueParameter<BoolValue>("ReevaluateElites", "Flag to determine if elite individuals should be reevaluated (i.e., if stochastic fitness functions are used.)", new BoolValue(false)) { Hidden = true });
+
+      Analyzer = new MultiAnalyzer();
+
+      foreach (ISelector selector in ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name))
+        SelectorParameter.ValidValues.Add(selector);
+      ISelector proportionalSelector = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("ProportionalSelector"));
+      if (proportionalSelector != null) SelectorParameter.Value = proportionalSelector;
+      ParameterizeSelectors();
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      ParameterizeAnalyzers();
+      UpdateAnalyzers();
+
+      RegisterEventHandlers();
+    }
+    [StorableConstructor]
+    private GeneticAlgorithm(bool deserializing) : base(deserializing) {
+      RegisterEventHandlers();
+    }
+
+    private GeneticAlgorithm(GeneticAlgorithm original, Cloner cloner)
+      : base(original, cloner) {
+      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+      RegisterEventHandlers();
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GeneticAlgorithm(this, cloner);
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+      var max = ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value;
+      Context.BestQuality = max ? double.MinValue : double.MaxValue;
+
+      for (var m = 0; m < PopulationSize; m++) {
+        Context.AddToPopulation(new SolutionScope(Problem.Evaluator.QualityParameter.ActualName));
+        Context.RunOperator(Problem.SolutionCreator, m, cancellationToken);
+      }
+
+      var locker = new object();
+      Parallel.For(0, PopulationSize, (i) => {
+        Context.RunOperator(Problem.Evaluator, Context.AtPopulation(i), cancellationToken);
+        var fit = Context.AtPopulation(i).Fitness;
+        if (max && Context.BestQuality < fit || !max && Context.BestQuality > fit) {
+          lock (locker) {
+            if (max && Context.BestQuality < fit || !max && Context.BestQuality > fit) {
+              Context.BestQuality = fit;
+            }
+          }
+        }
+      });
+
+      Context.EvaluatedSolutions += PopulationSize;
+
+      Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+      Results.Add(new Result("EvaluatedSolutions", new IntValue(Context.EvaluatedSolutions)));
+      Results.Add(new Result("BestQuality", new DoubleValue(Context.BestQuality)));
+
+      Context.RunOperator(Analyzer, cancellationToken);
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      var lastUpdate = ExecutionTime;
+      var max = ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value;
+
+      IResult result;
+      while (!StoppingCriterion()) {
+        Context.Iterations++;
+        
+        Context.RunOperator(Selector, cancellationToken);
+        var currentGen = Context.Scope.SubScopes[0];
+        var nextGen = Context.Scope.SubScopes[1];
+        for (var i = 0; i < PopulationSize - Elites; i++) {
+          var offspring = new SolutionScope(Problem.Evaluator.QualityParameter.ActualName);
+          var p1 = nextGen.SubScopes[0];
+          nextGen.SubScopes.RemoveAt(0);
+          offspring.SubScopes.Add(p1);
+          var p2 = nextGen.SubScopes[0];
+          nextGen.SubScopes.RemoveAt(0);
+          offspring.SubScopes.Add(p2);
+          nextGen.SubScopes.Add(offspring);
+
+          Context.RunOperator(Crossover, offspring, cancellationToken);
+          offspring.SubScopes.Clear();
+          if (Context.Random.NextDouble() < MutationProbability) {
+            Context.RunOperator(Mutator, offspring, cancellationToken);
+          }
+        }
+
+        var locker = new object();
+        Parallel.For(0, PopulationSize - Elites, (i) => {
+          Context.RunOperator(Problem.Evaluator, nextGen.SubScopes[i], cancellationToken);
+          var fit = ((ISolutionScope)nextGen.SubScopes[i]).Fitness;
+          if (max && Context.BestQuality < fit || !max && Context.BestQuality > fit) {
+            lock (locker) {
+              if (max && Context.BestQuality < fit || !max && Context.BestQuality > fit) {
+                Context.BestQuality = fit;
+              }
+            }
+          }
+        });
+        Context.EvaluatedSolutions += PopulationSize - Elites;
+        var elites = (max ? currentGen.SubScopes.OfType<SolutionScope>()
+          .OrderByDescending(x => x.Fitness).Take(Elites)
+          : currentGen.SubScopes.OfType<SolutionScope>()
+          .OrderBy(x => x.Fitness).Take(Elites)).ToList();
+        if (ReevaluteElites) {
+          Parallel.For(0, Elites, (i) => {
+            Context.RunOperator(Problem.Evaluator, elites[i], cancellationToken);
+          });
+          Context.EvaluatedSolutions += Elites;
+        }
+        nextGen.SubScopes.AddRange(elites);
+        Context.Scope.SubScopes.Replace(nextGen.SubScopes);
+
+        if (ExecutionTime - lastUpdate > TimeSpan.FromSeconds(1)) {
+          if (Results.TryGetValue("Iterations", out result))
+            ((IntValue)result.Value).Value = Context.Iterations;
+          else Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+          if (Results.TryGetValue("EvaluatedSolutions", out result))
+            ((IntValue)result.Value).Value = Context.EvaluatedSolutions;
+          else Results.Add(new Result("EvaluatedSolutions", new IntValue(Context.EvaluatedSolutions)));
+          lastUpdate = ExecutionTime;
+        }
+        if (Results.TryGetValue("BestQuality", out result))
+          ((DoubleValue)result.Value).Value = Context.BestQuality;
+        else Results.Add(new Result("BestQuality", new DoubleValue(Context.BestQuality)));
+
+        Context.RunOperator(Analyzer, cancellationToken);
+
+        if (cancellationToken.IsCancellationRequested) break;
+      }
+
+      if (Results.TryGetValue("Iterations", out result))
+        ((IntValue)result.Value).Value = Context.Iterations;
+      else Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+      if (Results.TryGetValue("EvaluatedSolutions", out result))
+        ((IntValue)result.Value).Value = Context.EvaluatedSolutions;
+      else Results.Add(new Result("EvaluatedSolutions", new IntValue(Context.EvaluatedSolutions)));
+      
+      if (Results.TryGetValue("BestQuality", out result))
+        ((DoubleValue) result.Value).Value = Context.BestQuality;
+      else Results.Add(new Result("BestQuality", new DoubleValue(Context.BestQuality)));
+    }
+
+    public override void Prepare() {
+      if (Problem != null) base.Prepare();
+    }
+
+    #region Events
+    protected override void OnProblemChanged() {
+      ParameterizeStochasticOperator(Problem.SolutionCreator);
+      ParameterizeStochasticOperator(Problem.Evaluator);
+      foreach (IOperator op in Problem.Operators.OfType<IOperator>()) ParameterizeStochasticOperator(op);
+      ParameterizeSelectors();
+      ParameterizeAnalyzers();
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+      UpdateAnalyzers();
+      Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      base.OnProblemChanged();
+    }
+    
+    protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      foreach (IOperator op in Problem.Operators.OfType<IOperator>()) ParameterizeStochasticOperator(op);
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+      UpdateAnalyzers();
+      base.Problem_OperatorsChanged(sender, e);
+    }
+    private void Elites_ValueChanged(object sender, EventArgs e) {
+      ParameterizeSelectors();
+    }
+    private void PopulationSize_ValueChanged(object sender, EventArgs e) {
+      ParameterizeSelectors();
+    }
+    private void Evaluator_QualityParameter_ActualNameChanged(object sender, EventArgs e) {
+      ParameterizeSelectors();
+      ParameterizeAnalyzers();
+    }
+    #endregion
+
+    #region Helpers
+    private void RegisterEventHandlers() {
+      PopulationSizeParameter.Value.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
+      ElitesParameter.Value.ValueChanged += new EventHandler(Elites_ValueChanged);
+      if (Problem != null) {
+        Problem.Evaluator.QualityParameter.ActualNameChanged += new EventHandler(Evaluator_QualityParameter_ActualNameChanged);
+      }
+    }
+    
+    private void ParameterizeStochasticOperator(IOperator op) {
+      IStochasticOperator stochasticOp = op as IStochasticOperator;
+      if (stochasticOp != null) {
+        stochasticOp.RandomParameter.ActualName = nameof(Context.Random);
+        stochasticOp.RandomParameter.Hidden = true;
+      }
+    }
+    private void ParameterizeSelectors() {
+      foreach (ISelector selector in SelectorParameter.ValidValues) {
+        selector.CopySelected = new BoolValue(true);
+        selector.NumberOfSelectedSubScopesParameter.Value = new IntValue(2 * (PopulationSizeParameter.Value.Value - ElitesParameter.Value.Value));
+        selector.NumberOfSelectedSubScopesParameter.Hidden = true;
+        ParameterizeStochasticOperator(selector);
+      }
+      if (Problem != null) {
+        foreach (ISingleObjectiveSelector selector in SelectorParameter.ValidValues.OfType<ISingleObjectiveSelector>()) {
+          selector.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+          selector.MaximizationParameter.Hidden = true;
+          selector.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+          selector.QualityParameter.Hidden = true;
+        }
+      }
+    }
+    private void ParameterizeAnalyzers() {
+      qualityAnalyzer.ResultsParameter.ActualName = "Results";
+      qualityAnalyzer.ResultsParameter.Hidden = true;
+      if (Problem != null) {
+        qualityAnalyzer.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+        qualityAnalyzer.MaximizationParameter.Hidden = true;
+        qualityAnalyzer.QualityParameter.ActualName = Problem.Evaluator.QualityParameter.ActualName;
+        qualityAnalyzer.QualityParameter.Depth = 1;
+        qualityAnalyzer.QualityParameter.Hidden = true;
+        qualityAnalyzer.BestKnownQualityParameter.ActualName = Problem.BestKnownQualityParameter.Name;
+        qualityAnalyzer.BestKnownQualityParameter.Hidden = true;
+      }
+    }
+    private void ParameterizeIterationBasedOperators() {
+      if (Problem != null) {
+        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
+          op.IterationsParameter.ActualName = "Generations";
+          op.IterationsParameter.Hidden = true;
+          op.MaximumIterationsParameter.ActualName = "MaximumGenerations";
+          op.MaximumIterationsParameter.Hidden = true;
+        }
+      }
+    }
+    private void UpdateCrossovers() {
+      ICrossover oldCrossover = CrossoverParameter.Value;
+      CrossoverParameter.ValidValues.Clear();
+      ICrossover defaultCrossover = Problem.Operators.OfType<ICrossover>().FirstOrDefault();
+
+      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
+        CrossoverParameter.ValidValues.Add(crossover);
+
+      if (oldCrossover != null) {
+        ICrossover crossover = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
+        if (crossover != null) CrossoverParameter.Value = crossover;
+        else oldCrossover = null;
+      }
+      if (oldCrossover == null && defaultCrossover != null)
+        CrossoverParameter.Value = defaultCrossover;
+    }
+    private void UpdateMutators() {
+      IManipulator oldMutator = MutatorParameter.Value;
+      MutatorParameter.ValidValues.Clear();
+      IManipulator defaultMutator = Problem.Operators.OfType<IManipulator>().FirstOrDefault();
+
+      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
+        MutatorParameter.ValidValues.Add(mutator);
+
+      if (oldMutator != null) {
+        IManipulator mutator = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
+        if (mutator != null) MutatorParameter.Value = mutator;
+        else oldMutator = null;
+      }
+
+      if (oldMutator == null && defaultMutator != null)
+        MutatorParameter.Value = defaultMutator;
+    }
+    private void UpdateAnalyzers() {
+      var multiAnalyzer = (MultiAnalyzer)Analyzer;
+      multiAnalyzer.Operators.Clear();
+      if (Problem != null) {
+        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
+          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 1;
+          multiAnalyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
+        }
+      }
+      multiAnalyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
+    }
+    #endregion
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/SolutionScope.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/SolutionScope.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Algorithms.GeneticAlgorithm/3.3/Model2/SolutionScope.cs	(revision 15625)
@@ -0,0 +1,35 @@
+﻿using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization.Model2;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.GeneticAlgorithm.Model2 {
+  [Item("GA Solution Scope", "")]
+  [StorableClass]
+  public class SolutionScope : Scope, ISolutionScope {
+
+    [Storable]
+    private Variable fitness;
+    public double Fitness {
+      get { return ((DoubleValue)fitness.Value).Value; }
+      set { ((DoubleValue)fitness.Value).Value = value; }
+    }
+
+    [StorableConstructor]
+    protected SolutionScope(bool deserializing) : base(deserializing) { }
+    protected SolutionScope(SolutionScope original, Cloner cloner)
+    : base(original, cloner) {
+      fitness = cloner.Clone(original.fitness);
+    }
+    public SolutionScope(string fitnessName) : this(fitnessName, double.NaN) { }
+    public SolutionScope(string fitnessName, double fitness) {
+      this.fitness = new Variable(fitnessName, new DoubleValue(fitness));
+      Variables.Add(this.fitness);
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SolutionScope(this, cloner);
+    }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Core/3.3/Scope.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Core/3.3/Scope.cs	(revision 15624)
+++ /branches/ContextAlgorithms/HeuristicLab.Core/3.3/Scope.cs	(revision 15625)
@@ -31,5 +31,5 @@
   [Item("Scope", "A scope which contains variables and sub-scopes.")]
   [StorableClass]
-  public sealed class Scope : NamedItem, IScope {
+  public class Scope : NamedItem, IScope {
     public static new Image StaticItemImage {
       get { return HeuristicLab.Common.Resources.VSImageLibrary.OrgChart; }
@@ -60,6 +60,6 @@
 
     [StorableConstructor]
-    private Scope(bool deserializing) : base(deserializing) { }
-    private Scope(Scope original, Cloner cloner)
+    protected Scope(bool deserializing) : base(deserializing) { }
+    protected Scope(Scope original, Cloner cloner)
       : base(original, cloner) {
       if (original.variables.Count > 0) variables = cloner.Clone(original.variables);
@@ -118,5 +118,5 @@
 
     #region SubScopes Events
-    private void RegisterSubScopesEvents() {
+    protected virtual void RegisterSubScopesEvents() {
       if (subScopes != null) {
         subScopes.ItemsAdded += new CollectionItemsChangedEventHandler<IndexedItem<IScope>>(SubScopes_ItemsAdded);
@@ -126,13 +126,13 @@
       }
     }
-    private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+    protected virtual void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
       foreach (IndexedItem<IScope> item in e.Items)
         item.Value.Parent = this;
     }
-    private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+    protected virtual void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
       foreach (IndexedItem<IScope> item in e.Items)
         item.Value.Parent = null;
     }
-    private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+    protected virtual void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
       foreach (IndexedItem<IScope> oldItem in e.OldItems)
         oldItem.Value.Parent = null;
@@ -140,5 +140,5 @@
         item.Value.Parent = this;
     }
-    private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+    protected virtual void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
       foreach (IndexedItem<IScope> oldItem in e.OldItems)
         oldItem.Value.Parent = null;
Index: /branches/ContextAlgorithms/HeuristicLab.MainForm.WindowsForms/3.3/Dialogs/InfoBox.resx
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.MainForm.WindowsForms/3.3/Dialogs/InfoBox.resx	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.MainForm.WindowsForms/3.3/Dialogs/InfoBox.resx	(revision 15625)
@@ -0,0 +1,120 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 15624)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 15625)
@@ -156,4 +156,12 @@
     <Compile Include="Interfaces\ILocalImprovementAlgorithmOperator.cs" />
     <Compile Include="Interfaces\IMultiObjectiveOperator.cs" />
+    <Compile Include="Model2\Algorithms\ContextAlgorithm.cs" />
+    <Compile Include="Model2\Algorithms\StochasticAlgorithm.cs" />
+    <Compile Include="Model2\Contexts\BasicContext.cs" />
+    <Compile Include="Model2\Contexts\PopulationContext.cs" />
+    <Compile Include="Model2\Contexts\SingleSolutionContext.cs" />
+    <Compile Include="Model2\Contexts\StochasticContext.cs" />
+    <Compile Include="Model2\Interfaces.cs" />
+    <Compile Include="Model2\SingleObjectiveSolutionScope.cs" />
     <Compile Include="MultiObjective\DominationCalculator.cs" />
     <Compile Include="Results\IResultParameter.cs" />
@@ -312,4 +320,9 @@
       <Private>False</Private>
     </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Random\3.3\HeuristicLab.Random-3.3.csproj">
+      <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project>
+      <Name>HeuristicLab.Random-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
   </ItemGroup>
   <ItemGroup>
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/ContextAlgorithm.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/ContextAlgorithm.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/ContextAlgorithm.cs	(revision 15625)
@@ -0,0 +1,110 @@
+﻿#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 System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Context-based Algorithm", "Algorithms that make use of contexts to facilitate applying operators.")]
+  [StorableClass]
+  public abstract class ContextAlgorithm<TContext> : BasicAlgorithm
+    where TContext : class, IContext, new() {
+    
+    [Storable]
+    private TContext context;
+    public TContext Context {
+      get { return context; }
+    }
+
+    [Storable]
+    private ValueParameter<IAnalyzer> analyzerParameter;
+    public IValueParameter<IAnalyzer> AnalyzerParameter {
+      get { return analyzerParameter; }
+    }
+    [Storable]
+    private FixedValueParameter<MultiTerminator> terminationParameter;
+    public IFixedValueParameter<MultiTerminator> TerminationParameter {
+      get { return terminationParameter; }
+    }
+
+    public IAnalyzer Analyzer {
+      get { return analyzerParameter.Value; }
+      set { analyzerParameter.Value = value; }
+    }
+    public MultiTerminator Termination {
+      get { return terminationParameter.Value; }
+    }
+
+    [StorableConstructor]
+    protected ContextAlgorithm(bool deserializing) : base(deserializing) { }
+    protected ContextAlgorithm(ContextAlgorithm<TContext> original, Cloner cloner)
+      : base(original, cloner) {
+      context = cloner.Clone(original.context);
+      analyzerParameter = cloner.Clone(original.analyzerParameter);
+      terminationParameter = cloner.Clone(original.terminationParameter);
+    }
+    protected ContextAlgorithm()
+      : base() {
+      Parameters.Add(analyzerParameter = new ValueParameter<IAnalyzer>("Analyzer", "The analyzers that are used to perform an analysis of the solutions."));
+      Parameters.Add(terminationParameter = new FixedValueParameter<MultiTerminator>("Termination", "The termination criteria that are being used.", new MultiTerminator()));
+
+      var generationsTerminator = new ComparisonTerminator<IntValue>("Iterations", ComparisonType.Less, new IntValue(1000)) { Name = "Iterations" };
+      var evaluationsTerminator = new ComparisonTerminator<IntValue>("EvaluatedSolutions", ComparisonType.Less, new IntValue(int.MaxValue)) { Name = "Evaluations" };
+      var executionTimeTerminator = new ExecutionTimeTerminator(this, new TimeSpanValue(TimeSpan.FromMinutes(5)));
+
+      Termination.AddOperator(generationsTerminator);
+      Termination.AddOperator(evaluationsTerminator);
+      Termination.AddOperator(executionTimeTerminator);
+
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+      context = new TContext();
+      context.Scope.Variables.Add(new Variable("Results", Results));
+
+      IExecutionContext ctxt = null;
+      foreach (var item in Problem.ExecutionContextItems)
+        ctxt = new Core.ExecutionContext(ctxt, item, Context.Scope);
+      ctxt = new Core.ExecutionContext(ctxt, this, Context.Scope);
+      context.Parent = ctxt;
+
+      context.Iterations = 0;
+      context.EvaluatedSolutions = 0;
+      context.BestQuality = double.NaN;
+    }
+
+    public override void Prepare() {
+      context = null;
+      base.Prepare();
+    }
+
+    protected virtual bool StoppingCriterion() {
+      Context.RunOperator(Termination, CancellationToken.None);
+      return Context.Terminate;
+    }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/StochasticAlgorithm.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/StochasticAlgorithm.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Algorithms/StochasticAlgorithm.cs	(revision 15625)
@@ -0,0 +1,80 @@
+﻿#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 System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Stochastic Algorithm", "Stochastic context-based algorithms to facilitate applying operators.")]
+  [StorableClass]
+  public abstract class StochasticAlgorithm<TContext> : ContextAlgorithm<TContext>
+    where TContext : class, IStochasticContext, new() {
+    
+    [Storable]
+    private FixedValueParameter<BoolValue> setSeedRandomlyParameter;
+    private IFixedValueParameter<BoolValue> SetSeedRandomlyParameter {
+      get { return setSeedRandomlyParameter; }
+    }
+    [Storable]
+    private FixedValueParameter<IntValue> seedParameter;
+    private IFixedValueParameter<IntValue> SeedParameter {
+      get { return seedParameter; }
+    }
+    
+    public bool SetSeedRandomly {
+      get { return setSeedRandomlyParameter.Value.Value; }
+      set { setSeedRandomlyParameter.Value.Value = value; }
+    }
+    public int Seed {
+      get { return seedParameter.Value.Value; }
+      set { seedParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected StochasticAlgorithm(bool deserializing) : base(deserializing) { }
+    protected StochasticAlgorithm(StochasticAlgorithm<TContext> original, Cloner cloner)
+      : base(original, cloner) {
+      setSeedRandomlyParameter = cloner.Clone(original.setSeedRandomlyParameter);
+      seedParameter = cloner.Clone(original.seedParameter);
+    }
+    protected StochasticAlgorithm()
+      : base() {
+      Parameters.Add(setSeedRandomlyParameter = new FixedValueParameter<BoolValue>("SetSeedRandomly", "Whether to overwrite the seed with a random value each time the algorithm is run.", new BoolValue(true)));
+      Parameters.Add(seedParameter = new FixedValueParameter<IntValue>("Seed", "The random seed that is used in the stochastic algorithm", new IntValue(0)));
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+
+      if (SetSeedRandomly) {
+        var rnd = new System.Random();
+        Seed = rnd.Next();
+      }
+
+      Context.Random = new MersenneTwister((uint)Seed);
+    }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/BasicContext.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/BasicContext.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/BasicContext.cs	(revision 15625)
@@ -0,0 +1,178 @@
+﻿#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 System;
+using System.Collections.Generic;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Basic Context", "A base class for algorithms' contexts.")]
+  [StorableClass]
+  public class BasicContext : ParameterizedNamedItem, IContext {
+
+    private IExecutionContext parent;
+    public IExecutionContext Parent {
+      get { return parent; }
+      set { parent = value; }
+    }
+
+    [Storable]
+    private IScope scope;
+    public IScope Scope {
+      get { return scope; }
+      private set { scope = value; }
+    }
+
+    IKeyedItemCollection<string, IParameter> IExecutionContext.Parameters {
+      get { return Parameters; }
+    }
+
+    [Storable]
+    private IFixedValueParameter<IntValue> iterations;
+    public int Iterations {
+      get { return iterations.Value.Value; }
+      set { iterations.Value.Value = value; }
+    }
+
+    [Storable]
+    private IFixedValueParameter<IntValue> evaluatedSolutions;
+    public int EvaluatedSolutions {
+      get { return evaluatedSolutions.Value.Value; }
+      set { evaluatedSolutions.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<DoubleValue> bestQuality;
+    public double BestQuality {
+      get { return bestQuality.Value.Value; }
+      set { bestQuality.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<BoolValue> terminate;
+    public bool Terminate {
+      get { return terminate.Value.Value; }
+      set { terminate.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected BasicContext(bool deserializing) : base(deserializing) { }
+    protected BasicContext(BasicContext original, Cloner cloner)
+    : base(original, cloner) {
+      scope = cloner.Clone(original.scope);
+      iterations = cloner.Clone(original.iterations);
+      evaluatedSolutions = cloner.Clone(original.evaluatedSolutions);
+      bestQuality = cloner.Clone(original.bestQuality);
+      terminate = cloner.Clone(original.terminate);
+    }
+    protected BasicContext() : base() {
+      scope = new Scope("Global");
+      Parameters.Add(iterations = new FixedValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new FixedValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(terminate = new ValueParameter<BoolValue>("Terminate", new BoolValue(false)));
+    }
+    protected BasicContext(string name) : base(name) {
+      scope = new Scope("Global");
+      Parameters.Add(iterations = new FixedValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new FixedValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(terminate = new ValueParameter<BoolValue>("Terminate", new BoolValue(false)));
+    }
+    protected BasicContext(string name, ParameterCollection parameters) : base(name, parameters) {
+      scope = new Scope("Global");
+      Parameters.Add(iterations = new FixedValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new FixedValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(terminate = new ValueParameter<BoolValue>("Terminate", new BoolValue(false)));
+    }
+    protected BasicContext(string name, string description) : base(name, description) {
+      scope = new Scope("Global");
+      Parameters.Add(iterations = new FixedValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new FixedValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(terminate = new ValueParameter<BoolValue>("Terminate", new BoolValue(false)));
+    }
+    protected BasicContext(string name, string description, ParameterCollection parameters) : base(name, description, parameters) {
+      scope = new Scope("Global");
+      Parameters.Add(iterations = new FixedValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new FixedValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(terminate = new ValueParameter<BoolValue>("Terminate", new BoolValue(false)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BasicContext(this, cloner);
+    }
+
+
+    public void RunOperator(IOperator op, CancellationToken cancellationToken) {
+      RunOperator(op, scope, cancellationToken);
+    }
+
+    public void RunOperator(IOperator op, IScope s, CancellationToken cancellationToken) {
+      if (op == null) return;
+      var stack = new Stack<IOperation>();
+      stack.Push(((IExecutionContext)this).CreateChildOperation(op, s));
+
+      while (stack.Count > 0) {
+        cancellationToken.ThrowIfCancellationRequested();
+
+        var next = stack.Pop();
+        if (next is OperationCollection) {
+          var coll = (OperationCollection)next;
+          for (int i = coll.Count - 1; i >= 0; i--)
+            if (coll[i] != null) stack.Push(coll[i]);
+        } else if (next is IAtomicOperation) {
+          var operation = (IAtomicOperation)next;
+          try {
+            next = operation.Operator.Execute((IExecutionContext)operation, cancellationToken);
+          } catch (Exception ex) {
+            stack.Push(operation);
+            if (ex is OperationCanceledException) throw ex;
+            else throw new OperatorExecutionException(operation.Operator, ex);
+          }
+          if (next != null) stack.Push(next);
+        }
+      }
+    }
+
+    #region IExecutionContext members
+    IAtomicOperation IExecutionContext.CreateOperation(IOperator op) {
+      return new Core.ExecutionContext(this, op, Scope);
+    }
+    IAtomicOperation IExecutionContext.CreateOperation(IOperator op, IScope s) {
+      return new Core.ExecutionContext(this, op, s);
+    }
+    IAtomicOperation IExecutionContext.CreateChildOperation(IOperator op) {
+      return new Core.ExecutionContext(this, op, Scope);
+    }
+    IAtomicOperation IExecutionContext.CreateChildOperation(IOperator op, IScope s) {
+      return new Core.ExecutionContext(this, op, s);
+    }
+    #endregion
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/PopulationContext.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/PopulationContext.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/PopulationContext.cs	(revision 15625)
@@ -0,0 +1,77 @@
+﻿#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 System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Population Context", "A context for population-based algorithms.")]
+  [StorableClass]
+  public class PopulationContext<TSolutionScope> : StochasticContext
+    where TSolutionScope: class, IScope {
+
+    public IEnumerable<TSolutionScope> Population {
+      get { return Scope.SubScopes.OfType<TSolutionScope>(); }
+    }
+    public void AddToPopulation(TSolutionScope solScope) {
+      Scope.SubScopes.Add(solScope);
+    }
+    public void ReplaceAtPopulation(int index, TSolutionScope solScope) {
+      Scope.SubScopes[index] = solScope;
+    }
+    public void ReplacePopulation(IEnumerable<TSolutionScope> replacement) {
+      Scope.SubScopes.Replace(replacement);
+    }
+    public TSolutionScope AtPopulation(int index) {
+      return Scope.SubScopes[index] as TSolutionScope;
+    }
+    public TSolutionScope AtRandomPopulation() {
+      return Scope.SubScopes[Random.Next(PopulationCount)] as TSolutionScope;
+    }
+    public int PopulationCount {
+      get { return Scope.SubScopes.Count; }
+    }
+
+
+    [StorableConstructor]
+    protected PopulationContext(bool deserializing) : base(deserializing) { }
+    protected PopulationContext(PopulationContext<TSolutionScope> original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public PopulationContext() : base() { }
+    public PopulationContext(string name) : base(name) { }
+    public PopulationContext(string name, ParameterCollection parameters) : base(name, parameters) { }
+    public PopulationContext(string name, string description) : base(name, description) { }
+    public PopulationContext(string name, string description, ParameterCollection parameters) : base(name, description, parameters) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PopulationContext<TSolutionScope>(this, cloner);
+    }
+
+    public void RunOperator(IOperator op, int individual, CancellationToken cancellationToken) {
+      RunOperator(op, AtPopulation(individual), cancellationToken);
+    }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/SingleSolutionContext.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/SingleSolutionContext.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/SingleSolutionContext.cs	(revision 15625)
@@ -0,0 +1,57 @@
+﻿#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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Single Solution Context", "A context for single solution algorithms.")]
+  [StorableClass]
+  public abstract class SingleSolutionContext<TSolutionScope> : StochasticContext
+    where TSolutionScope: class, IScope {
+    
+    [Storable]
+    private TSolutionScope incumbent;
+    public TSolutionScope Incumbent {
+      get { return incumbent; }
+    }
+
+    public void ReplaceIncumbent(TSolutionScope solScope) {
+      if (incumbent != null) Scope.SubScopes.Remove(incumbent);
+      this.incumbent = solScope;
+      if (incumbent != null) Scope.SubScopes.Add(incumbent);
+    }
+
+
+    [StorableConstructor]
+    protected SingleSolutionContext(bool deserializing) : base(deserializing) { }
+    protected SingleSolutionContext(SingleSolutionContext<TSolutionScope> original, Cloner cloner)
+      : base(original, cloner) {
+      incumbent = cloner.Clone(original.incumbent);
+    }
+    protected SingleSolutionContext() : base() { }
+    protected SingleSolutionContext(string name) : base(name) { }
+    protected SingleSolutionContext(string name, ParameterCollection parameters) : base(name, parameters) { }
+    protected SingleSolutionContext(string name, string description) : base(name, description) { }
+    protected SingleSolutionContext(string name, string description, ParameterCollection parameters) : base(name, description, parameters) { }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/StochasticContext.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/StochasticContext.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Contexts/StochasticContext.cs	(revision 15625)
@@ -0,0 +1,65 @@
+﻿#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.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Stochastic Context", "A base class for stochastic algorithms' contexts.")]
+  [StorableClass]
+  public class StochasticContext : BasicContext, IStochasticContext {
+    
+    [Storable]
+    private IValueParameter<IRandom> random;
+    public IRandom Random {
+      get { return random.Value; }
+      set { random.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected StochasticContext(bool deserializing) : base(deserializing) { }
+    protected StochasticContext(StochasticContext original, Cloner cloner)
+    : base(original, cloner) {
+      random = cloner.Clone(original.random);
+    }
+    protected StochasticContext() : base() {
+      Parameters.Add(random = new ValueParameter<IRandom>("Random"));
+    }
+    protected StochasticContext(string name) : base(name) {
+      Parameters.Add(random = new ValueParameter<IRandom>("Random"));
+    }
+    protected StochasticContext(string name, ParameterCollection parameters) : base(name, parameters) {
+      Parameters.Add(random = new ValueParameter<IRandom>("Random"));
+    }
+    protected StochasticContext(string name, string description) : base(name, description) {
+      Parameters.Add(random = new ValueParameter<IRandom>("Random"));
+    }
+    protected StochasticContext(string name, string description, ParameterCollection parameters) : base(name, description, parameters) {
+      Parameters.Add(random = new ValueParameter<IRandom>("Random"));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new StochasticContext(this, cloner);
+    }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Interfaces.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Interfaces.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/Interfaces.cs	(revision 15625)
@@ -0,0 +1,47 @@
+﻿#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 System.Threading;
+using HeuristicLab.Core;
+
+namespace HeuristicLab.Optimization.Model2 {
+  public interface ISolutionScope : IScope {
+    double Fitness { get; set; }
+  }
+
+  public interface ISolutionScope<TSolution> : ISolutionScope {
+    TSolution Solution { get; set; }
+  }
+
+  public interface IContext : IExecutionContext {
+    new IExecutionContext Parent { get; set; }
+    int Iterations { get; set; }
+    int EvaluatedSolutions { get; set; }
+    double BestQuality { get; set; }
+    bool Terminate { get; set; }
+
+    void RunOperator(IOperator op, CancellationToken token);
+  }
+
+  public interface IStochasticContext : IContext {
+    IRandom Random { get; set; }
+  }
+}
Index: /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/SingleObjectiveSolutionScope.cs
===================================================================
--- /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/SingleObjectiveSolutionScope.cs	(revision 15625)
+++ /branches/ContextAlgorithms/HeuristicLab.Optimization/3.3/Model2/SingleObjectiveSolutionScope.cs	(revision 15625)
@@ -0,0 +1,137 @@
+﻿#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 System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Optimization.Model2 {
+  [Item("Solution Scope", "Scope for an individual/solution of a single-objective single-encoded problem.")]
+  [StorableClass]
+  public sealed class SingleObjectiveSolutionScope<T> : NamedItem, ISolutionScope<T> where T : class, IItem {
+    public new static Image StaticItemImage {
+      get { return HeuristicLab.Common.Resources.VSImageLibrary.OrgChart; }
+    }
+
+    [Storable]
+    private IScope parent;
+    public IScope Parent {
+      get { return parent; }
+      set {
+        if (parent != value) {
+          parent = value;
+        }
+      }
+    }
+
+    [Storable]
+    private VariableCollection variables;
+    public VariableCollection Variables {
+      get { return variables; }
+    }
+
+    [Storable]
+    private ScopeList subScopes;
+    public ScopeList SubScopes {
+      get { return subScopes; }
+    }
+
+    [Storable]
+    private Variable solution;
+    public T Solution {
+      get { return (T)solution.Value; }
+      set { solution.Value = value; }
+    }
+
+    [Storable]
+    private Variable fitness;
+    public double Fitness {
+      get { return ((DoubleValue)fitness.Value).Value; }
+      set { ((DoubleValue)fitness.Value).Value = value; }
+    }
+
+    [StorableConstructor]
+    private SingleObjectiveSolutionScope(bool deserializing) : base(deserializing) { }
+    private SingleObjectiveSolutionScope(SingleObjectiveSolutionScope<T> original, Cloner cloner)
+      : base(original, cloner) {
+      // the parent will not be deep-cloned
+      parent = original.parent;
+      variables = cloner.Clone(original.variables);
+      subScopes = cloner.Clone(original.subScopes);
+      foreach (var child in SubScopes)
+        child.Parent = this;
+      solution = cloner.Clone(original.solution);
+      fitness = cloner.Clone(original.fitness);
+
+      RegisterSubScopesEvents();
+    }
+    public SingleObjectiveSolutionScope(T code, string codeName, double fitness, string fitnessName) {
+      this.solution = new Variable(codeName, code);
+      this.fitness = new Variable(fitnessName, new DoubleValue(fitness));
+      variables = new VariableCollection(2) { this.solution, this.fitness };
+      subScopes = new ScopeList(2);
+
+      RegisterSubScopesEvents();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new SingleObjectiveSolutionScope<T>(this, cloner);
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterSubScopesEvents();
+    }
+
+    public void Clear() {
+      variables.Clear();
+      subScopes.Clear();
+    }
+
+    #region SubScopes Events
+    private void RegisterSubScopesEvents() {
+      if (subScopes != null) {
+        subScopes.ItemsAdded += SubScopes_ItemsAdded;
+        subScopes.ItemsRemoved += SubScopes_ItemsRemoved;
+        subScopes.ItemsReplaced += SubScopes_ItemsReplaced;
+        subScopes.CollectionReset += SubScopes_CollectionReset;
+      }
+    }
+    private void SubScopes_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+      foreach (var item in e.Items) item.Value.Parent = this;
+    }
+    private void SubScopes_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+      foreach (var item in e.Items) item.Value.Parent = null;
+    }
+    private void SubScopes_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+      foreach (var oldItem in e.OldItems) oldItem.Value.Parent = null;
+      foreach (var item in e.Items) item.Value.Parent = this;
+    }
+    private void SubScopes_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IScope>> e) {
+      foreach (var oldItem in e.OldItems) oldItem.Value.Parent = null;
+      foreach (var item in e.Items) item.Value.Parent = this;
+    }
+    #endregion
+  }
+}
