Index: branches/ScopedBasicAlgorithm/HeuristicLab 3.3.sln
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab 3.3.sln	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab 3.3.sln	(revision 14420)
@@ -2,5 +2,5 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 14
-VisualStudioVersion = 14.0.23107.0
+VisualStudioVersion = 14.0.25420.1
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}"
@@ -32,4 +32,5 @@
 		{CB3D0A1E-1BE8-476B-A53C-2B189E30064F} = {CB3D0A1E-1BE8-476B-A53C-2B189E30064F}
 		{D34A7620-3E23-40D9-8647-637BE901F271} = {D34A7620-3E23-40D9-8647-637BE901F271}
+		{9D274421-6332-4FBC-AAE4-467ACE27C368} = {9D274421-6332-4FBC-AAE4-467ACE27C368}
 		{E0B45023-CB84-48A1-A1B7-8295B64B7BAD} = {E0B45023-CB84-48A1-A1B7-8295B64B7BAD}
 		{C633FB23-BAE6-448E-BF5D-E1F9A839B5ED} = {C633FB23-BAE6-448E-BF5D-E1F9A839B5ED}
@@ -449,4 +450,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.BinPacking-3.3", "HeuristicLab.Problems.BinPacking\3.3\HeuristicLab.Problems.BinPacking-3.3.csproj", "{F8A55094-3CD5-4034-B0CA-5BD7FFB016D4}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Algorithms.MemPR-3.3", "HeuristicLab.Algorithms.MemPR\3.3\HeuristicLab.Algorithms.MemPR-3.3.csproj", "{9D274421-6332-4FBC-AAE4-467ACE27C368}"
 EndProject
 Global
@@ -2188,4 +2191,16 @@
 		{F8A55094-3CD5-4034-B0CA-5BD7FFB016D4}.Release|x86.ActiveCfg = Release|x86
 		{F8A55094-3CD5-4034-B0CA-5BD7FFB016D4}.Release|x86.Build.0 = Release|x86
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|x64.ActiveCfg = Debug|x64
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|x64.Build.0 = Debug|x64
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|x86.ActiveCfg = Debug|x86
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Debug|x86.Build.0 = Debug|x86
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|Any CPU.Build.0 = Release|Any CPU
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|x64.ActiveCfg = Release|x64
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|x64.Build.0 = Release|x64
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|x86.ActiveCfg = Release|x86
+		{9D274421-6332-4FBC-AAE4-467ACE27C368}.Release|x86.Build.0 = Release|x86
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPR.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPR.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPR.cs	(revision 14420)
@@ -0,0 +1,263 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.LocalSearch;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MemPR.Binary {
+  [Item("MemPR (binary)", "MemPR implementation for binary vectors.")]
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.PopulationBasedAlgorithms, Priority = 999)]
+  public class BinaryMemPR : MemPRAlgorithm<BinaryVector, BinaryMemPRContext, BinarySingleSolutionMemPRContext> {
+    private const double UncommonBitSubsetMutationProbabilityMagicConst = 0.05;
+    
+    [StorableConstructor]
+    protected BinaryMemPR(bool deserializing) : base(deserializing) { }
+    protected BinaryMemPR(BinaryMemPR original, Cloner cloner) : base(original, cloner) { }
+    public BinaryMemPR() {
+      foreach (var trainer in ApplicationManager.Manager.GetInstances<IBinarySolutionModelTrainer<BinaryMemPRContext>>())
+        SolutionModelTrainerParameter.ValidValues.Add(trainer);
+      
+      foreach (var localSearch in ApplicationManager.Manager.GetInstances<IBinaryLocalSearch<BinarySingleSolutionMemPRContext>>()) {
+        // only use local search operators that can deal with a restricted solution space
+        var lsType = localSearch.GetType();
+        var genTypeDef = lsType.GetGenericTypeDefinition();
+        // TODO: By convention, context type must be put last
+        // TODO: Fails with non-generic types
+        if (genTypeDef.GetGenericArguments().Last().GetGenericParameterConstraints().Any(x => typeof(IBinarySolutionSubspaceContext).IsAssignableFrom(x))) {
+          localSearch.EvaluateFunc = EvaluateFunc;
+          LocalSearchParameter.ValidValues.Add(localSearch);
+        }
+      }
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryMemPR(this, cloner);
+    }
+
+    protected double EvaluateFunc(BinaryVector solution) {
+      var scope = ToScope(solution);
+      Evaluate(scope, CancellationToken.None);
+      return scope.Fitness;
+    }
+
+    protected override bool Eq(ISingleObjectiveSolutionScope<BinaryVector> a, ISingleObjectiveSolutionScope<BinaryVector> b) {
+      var len = a.Solution.Length;
+      var acode = a.Solution;
+      var bcode = b.Solution;
+      for (var i = 0; i < len; i++)
+        if (acode[i] != bcode[i]) return false;
+      return true;
+    }
+
+    protected override double Dist(ISingleObjectiveSolutionScope<BinaryVector> a, ISingleObjectiveSolutionScope<BinaryVector> b) {
+      var len = a.Solution.Length;
+      var acode = a.Solution;
+      var bcode = b.Solution;
+      var hamming = 0;
+      for (var i = 0; i < len; i++)
+        if (acode[i] != bcode[i]) hamming++;
+      return hamming / (double)len;
+    }
+
+    protected override ISingleObjectiveSolutionScope<BinaryVector> ToScope(BinaryVector code, double fitness = double.NaN) {
+      var creator = Problem.SolutionCreator as IBinaryVectorCreator;
+      if (creator == null) throw new InvalidOperationException("Can only solve binary encoded problems with MemPR (binary)");
+      return new SingleObjectiveSolutionScope<BinaryVector>(code, creator.BinaryVectorParameter.ActualName, fitness, Problem.Evaluator.QualityParameter.ActualName) {
+        Parent = Context.Scope
+      };
+    }
+
+    protected override ISolutionSubspace CalculateSubspace(IEnumerable<BinaryVector> solutions, bool inverse = false) {
+      var pop = solutions.ToList();
+      var N = pop[0].Length;
+      var subspace = new bool[N];
+      for (var i = 0; i < N; i++) {
+        var val = pop[0][i];
+        if (inverse) subspace[i] = true;
+        for (var p = 1; p < pop.Count; p++) {
+          if (pop[p][i] != val) subspace[i] = !inverse;
+        }
+      }
+      return new BinarySolutionSubspace(subspace);
+    }
+
+    protected override ISingleObjectiveSolutionScope<BinaryVector> Create(CancellationToken token) {
+      var child = ToScope(null);
+      RunOperator(Problem.SolutionCreator, child, token);
+      return child;
+    }
+
+    protected override void TabuWalk(ISingleObjectiveSolutionScope<BinaryVector> scope, int steps, CancellationToken token, ISolutionSubspace subspace = null) {
+      var subset = subspace != null ? ((BinarySolutionSubspace)subspace).Subspace : null;
+      if (double.IsNaN(scope.Fitness)) Evaluate(scope, token);
+      SingleObjectiveSolutionScope<BinaryVector> bestOfTheWalk = null;
+      var currentScope = (SingleObjectiveSolutionScope<BinaryVector>)scope.Clone();
+      var current = currentScope.Solution;
+      var N = current.Length;
+      var tabu = new Tuple<double, double>[N];
+      for (var i = 0; i < N; i++) tabu[i] = Tuple.Create(current[i] ? double.NaN : currentScope.Fitness, !current[i] ? double.NaN : currentScope.Fitness);
+      var subN = subset != null ? subset.Count(x => x) : N;
+      if (subN == 0) return;
+      var order = Enumerable.Range(0, N).Where(x => subset == null || subset[x]).Shuffle(Context.Random).ToArray();
+
+      for (var iter = 0; iter < steps; iter++) {
+        var allTabu = true;
+        var bestOfTheRestF = double.NaN;
+        int bestOfTheRest = -1;
+        var improved = false;
+
+        for (var i = 0; i < subN; i++) {
+          var idx = order[i];
+          var before = currentScope.Fitness;
+          current[idx] = !current[idx];
+          Evaluate(currentScope, token);
+          var after = currentScope.Fitness;
+
+          if (IsBetter(after, before) && (bestOfTheWalk == null || IsBetter(after, bestOfTheWalk.Fitness))) {
+            bestOfTheWalk = (SingleObjectiveSolutionScope<BinaryVector>)currentScope.Clone();
+          }
+
+          var qualityToBeat = current[idx] ? tabu[idx].Item2 : tabu[idx].Item1;
+          var isTabu = !IsBetter(after, qualityToBeat);
+          if (!isTabu) allTabu = false;
+
+          if (IsBetter(after, before) && !isTabu) {
+            improved = true;
+            tabu[idx] = current[idx] ? Tuple.Create(after, tabu[idx].Item2) : Tuple.Create(tabu[idx].Item1, after);
+          } else { // undo the move
+            if (!isTabu && IsBetter(after, bestOfTheRestF)) {
+              bestOfTheRest = idx;
+              bestOfTheRestF = after;
+            }
+            current[idx] = !current[idx];
+            currentScope.Fitness = before;
+          }
+        }
+        if (!allTabu && !improved) {
+          var better = currentScope.Fitness;
+          current[bestOfTheRest] = !current[bestOfTheRest];
+          tabu[bestOfTheRest] = current[bestOfTheRest] ? Tuple.Create(better, tabu[bestOfTheRest].Item2) : Tuple.Create(tabu[bestOfTheRest].Item1, better);
+          currentScope.Fitness = bestOfTheRestF;
+        } else if (allTabu) break;
+      }
+
+      scope.Adopt(bestOfTheWalk ?? currentScope);
+    }
+
+    protected override ISingleObjectiveSolutionScope<BinaryVector> Cross(ISingleObjectiveSolutionScope<BinaryVector> p1, ISingleObjectiveSolutionScope<BinaryVector> p2, CancellationToken token) {
+      var offspring = (ISingleObjectiveSolutionScope<BinaryVector>)p1.Clone();
+      offspring.Fitness = double.NaN;
+      var code = offspring.Solution;
+      var p2Code = p2.Solution;
+      var bp = 0;
+      var lastbp = 0;
+      for (var i = 0; i < code.Length; i++) {
+        if (code[i] == p2Code[i]) continue; // common bit
+        if (bp % 2 == 1) {
+          code[i] = p2Code[i];
+        }
+        if (Context.Random.Next(code.Length) < i - lastbp) {
+          bp = (bp + 1) % 2;
+          lastbp = i;
+        }
+      }
+      return offspring;
+    }
+
+    protected override void Mutate(ISingleObjectiveSolutionScope<BinaryVector> offspring, CancellationToken token, ISolutionSubspace subspace = null) {
+      var subset = subspace != null ? ((BinarySolutionSubspace)subspace).Subspace : null;
+      offspring.Fitness = double.NaN;
+      var code = offspring.Solution;
+      for (var i = 0; i < code.Length; i++) {
+        if (subset != null && subset[i]) continue;
+        if (Context.Random.NextDouble() < UncommonBitSubsetMutationProbabilityMagicConst) {
+          code[i] = !code[i];
+          if (subset != null) subset[i] = true;
+        }
+      }
+    }
+
+    protected override ISingleObjectiveSolutionScope<BinaryVector> Relink(ISingleObjectiveSolutionScope<BinaryVector> a, ISingleObjectiveSolutionScope<BinaryVector> b, CancellationToken token) {
+      if (double.IsNaN(a.Fitness)) Evaluate(a, token);
+      if (double.IsNaN(b.Fitness)) Evaluate(b, token);
+      if (Context.Random.NextDouble() < 0.5)
+        return IsBetter(a, b) ? Relink(a, b, token, false) : Relink(b, a, token, true);
+      else return IsBetter(a, b) ? Relink(b, a, token, true) : Relink(a, b, token, false);
+    }
+
+    protected virtual ISingleObjectiveSolutionScope<BinaryVector> Relink(ISingleObjectiveSolutionScope<BinaryVector> betterScope, ISingleObjectiveSolutionScope<BinaryVector> worseScope, CancellationToken token, bool fromWorseToBetter) {
+      var childScope = (ISingleObjectiveSolutionScope<BinaryVector>)(fromWorseToBetter ? worseScope : betterScope).Clone();
+      var child = childScope.Solution;
+      var better = betterScope.Solution;
+      var worse = worseScope.Solution;
+      ISingleObjectiveSolutionScope<BinaryVector> best = null;
+      var cF = fromWorseToBetter ? worseScope.Fitness : betterScope.Fitness;
+      var bF = double.NaN;
+      var order = Enumerable.Range(0, better.Length).Shuffle(Context.Random).ToArray();
+      while (true) {
+        var bestS = double.NaN;
+        var bestIdx = -1;
+        for (var i = 0; i < child.Length; i++) {
+          var idx = order[i];
+          // either move from worse to better or move from better away from worse
+          if (fromWorseToBetter && child[idx] == better[idx] ||
+            !fromWorseToBetter && child[idx] != worse[idx]) continue;
+          child[idx] = !child[idx]; // move
+          Evaluate(childScope, token);
+          var s = childScope.Fitness;
+          childScope.Fitness = cF;
+          child[idx] = !child[idx]; // undo move
+          if (IsBetter(s, cF)) {
+            bestS = s;
+            bestIdx = idx;
+            break; // first-improvement
+          }
+          if (double.IsNaN(bestS) || IsBetter(s, bestS)) {
+            // least-degrading
+            bestS = s;
+            bestIdx = idx;
+          }
+        }
+        if (bestIdx < 0) break;
+        child[bestIdx] = !child[bestIdx];
+        cF = bestS;
+        childScope.Fitness = cF;
+        if (IsBetter(cF, bF)) {
+          bF = cF;
+          best = (ISingleObjectiveSolutionScope<BinaryVector>)childScope.Clone();
+        }
+      }
+      return best ?? childScope;
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPRContext.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPRContext.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinaryMemPRContext.cs	(revision 14420)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MemPR.Binary {
+  [Item("BinaryMemPRContext", "MemPR context for binary encoded problems.")]
+  [StorableClass]
+  public sealed class BinaryMemPRContext : MemPRContext<BinaryVector, BinaryMemPRContext, BinarySingleSolutionMemPRContext> {
+
+    [StorableConstructor]
+    private BinaryMemPRContext(bool deserializing) : base(deserializing) { }
+    private BinaryMemPRContext(BinaryMemPRContext original, Cloner cloner)
+      : base(original, cloner) { }
+    public BinaryMemPRContext() : base("BinaryMemPRContext") { }
+    public BinaryMemPRContext(string name) : base(name) { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryMemPRContext(this, cloner);
+    }
+
+    public override BinarySingleSolutionMemPRContext CreateSingleSolutionContext(ISingleObjectiveSolutionScope<BinaryVector> solution) {
+      return new BinarySingleSolutionMemPRContext(this, solution);
+    }
+  }
+
+  [Item("BinarySingleSolutionMemPRContext", "Single solution MemPR context for binary encoded problems.")]
+  [StorableClass]
+  public sealed class BinarySingleSolutionMemPRContext : SingleSolutionMemPRContext<BinaryVector, BinaryMemPRContext, BinarySingleSolutionMemPRContext>, IBinarySolutionSubspaceContext {
+
+    [Storable]
+    private IValueParameter<BinarySolutionSubspace> subspace;
+    public BinarySolutionSubspace Subspace {
+      get { return subspace.Value; }
+    }
+    ISolutionSubspace ISolutionSubspaceContext.Subspace {
+      get { return Subspace; }
+    }
+
+    [StorableConstructor]
+    private BinarySingleSolutionMemPRContext(bool deserializing) : base(deserializing) { }
+    private BinarySingleSolutionMemPRContext(BinarySingleSolutionMemPRContext original, Cloner cloner)
+      : base(original, cloner) {
+
+    }
+    public BinarySingleSolutionMemPRContext(BinaryMemPRContext baseContext, ISingleObjectiveSolutionScope<BinaryVector> solution)
+      : base(baseContext, solution) {
+
+      Parameters.Add(subspace = new ValueParameter<BinarySolutionSubspace>("Subspace", new BinarySolutionSubspace(null)));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinarySingleSolutionMemPRContext(this, cloner);
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinarySolutionSubspace.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinarySolutionSubspace.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/BinarySolutionSubspace.cs	(revision 14420)
@@ -0,0 +1,50 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MemPR.Binary {
+  [Item("Solution subspace (binary)", "")]
+  [StorableClass]
+  public sealed class BinarySolutionSubspace : Item, ISolutionSubspace {
+
+    [Storable]
+    private bool[] subspace;
+    public bool[] Subspace { get { return subspace; } }
+
+    [StorableConstructor]
+    private BinarySolutionSubspace(bool deserializing) : base(deserializing) { }
+    private BinarySolutionSubspace(BinarySolutionSubspace original, Cloner cloner)
+      : base(original, cloner) {
+      subspace = (bool[])original.subspace.Clone();
+    }
+    public BinarySolutionSubspace(bool[] subspace) {
+      this.subspace = subspace;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinarySolutionSubspace(this, cloner);
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflip.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflip.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflip.cs	(revision 14420)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.LocalSearch;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.LocalSearch {
+  [Item("Exhaustive Bitflip Local Search (binary)", "")]
+  [StorableClass]
+  public class ExhaustiveBitflip<TContext> : ExhaustiveBitflipOperator, IBinaryLocalSearch<TContext> 
+      where TContext : ISingleObjectiveSolutionContext<BinaryVector>, IStochasticContext, IMaximizationContext,
+                       IEvaluatedSolutionsContext, IIterationsManipulationContext {
+    
+    [StorableConstructor]
+    protected ExhaustiveBitflip(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveBitflip(ExhaustiveBitflip<TContext> original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveBitflip() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveBitflip<TContext>(this, cloner);
+    }
+
+    public void Optimize(TContext context) {
+      var quality = context.Solution.Fitness;
+      try {
+        var result = Heuristic.ExhaustiveBitFlipSearch(context.Random, context.Solution.Solution, ref quality,
+          context.Maximization, EvaluateFunc, CancellationToken);
+        context.EvaluatedSolutions = result.Item1;
+        context.Iterations = result.Item2;
+      } finally {
+        context.Solution.Fitness = quality;
+      }
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipOperator.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipOperator.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipOperator.cs	(revision 14420)
@@ -0,0 +1,89 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.LocalSearch;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.LocalSearch {
+  [Item("Exhaustive Bitflip Local Search Operator (binary)", "")]
+  [StorableClass]
+  public class ExhaustiveBitflipOperator : SingleSuccessorOperator, ILocalSearch<BinaryVector>, ISingleObjectiveOperator, IStochasticOperator {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    
+    public ILookupParameter<BinaryVector> SolutionParameter {
+      get { return (ILookupParameter<BinaryVector>)Parameters["Solution"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public ILookupParameter<BoolArray> SubspaceParameter {
+      get { return (ILookupParameter<BoolArray>)Parameters["Subspace"]; }
+    }
+
+    public Func<BinaryVector, double> EvaluateFunc { get; set; }
+
+    [StorableConstructor]
+    protected ExhaustiveBitflipOperator(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveBitflipOperator(ExhaustiveBitflipOperator original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveBitflipOperator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<BinaryVector>("Solution", "The solution that is to be optimized"));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether the solution's quality should be maximized or minimized."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The quality of the solution."));
+      Parameters.Add(new LookupParameter<BoolArray>("Subspace", "Whether the local search should be confined to a sub-space of the solution space (indicated by true in this vector)."));
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveBitflipOperator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      var quality = QualityParameter.ActualValue.Value;
+      var subspace = SubspaceParameter.ActualValue != null ? SubspaceParameter.ActualValue.ToArray() : null;
+      try {
+        Heuristic.ExhaustiveBitFlipSearch(RandomParameter.ActualValue,
+          SolutionParameter.ActualValue, ref quality, MaximizationParameter.ActualValue.Value,
+          EvaluateFunc, CancellationToken, subspace);
+      } finally {
+        QualityParameter.ActualValue.Value = quality;
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipSubspace.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipSubspace.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/ExhaustiveBitflipSubspace.cs	(revision 14420)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.LocalSearch;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.LocalSearch {
+  [Item("Exhaustive Bitflip Local (Subspace) Search (binary)", "")]
+  [StorableClass]
+  public class ExhaustiveBitflipSubspace<TContext> : ExhaustiveBitflipOperator, IBinaryLocalSearch<TContext>
+      where TContext : ISingleObjectiveSolutionContext<BinaryVector>, IStochasticContext, IMaximizationContext,
+                       IEvaluatedSolutionsContext, IIterationsManipulationContext, IBinarySolutionSubspaceContext {
+
+    [StorableConstructor]
+    protected ExhaustiveBitflipSubspace(bool deserializing) : base(deserializing) { }
+    protected ExhaustiveBitflipSubspace(ExhaustiveBitflipSubspace<TContext> original, Cloner cloner) : base(original, cloner) { }
+    public ExhaustiveBitflipSubspace() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ExhaustiveBitflipSubspace<TContext>(this, cloner);
+    }
+
+    public void Optimize(TContext context) {
+      var quality = context.Solution.Fitness;
+      try {
+        var result = Heuristic.ExhaustiveBitFlipSearch(context.Random, context.Solution.Solution, ref quality,
+          context.Maximization, EvaluateFunc, CancellationToken, context.Subspace != null ? context.Subspace.Subspace : null);
+        context.EvaluatedSolutions = result.Item1;
+        context.Iterations = result.Item2;
+      } finally {
+        context.Solution.Fitness = quality;
+      }
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/Heuristic.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/Heuristic.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/LocalSearch/Heuristic.cs	(revision 14420)
@@ -0,0 +1,71 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Linq;
+using System.Threading;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.Binary.LocalSearch {
+  public static class Heuristic {
+    private static bool IsBetter(bool maximization, double a, double b) {
+      return maximization && a > b
+        || !maximization && a < b;
+    }
+
+    public static Tuple<int, int> ExhaustiveBitFlipSearch(IRandom random, BinaryVector solution, ref double quality, bool maximization, Func<BinaryVector, double> evalFunc, CancellationToken token, bool[] subspace = null) {
+      if (double.IsNaN(quality)) quality = evalFunc(solution);
+      var improved = false;
+      var order = Enumerable.Range(0, solution.Length).Shuffle(random).ToArray();
+      var lastImp = -1;
+      var steps = 0;
+      var evaluations = 0;
+      do {
+        improved = false;
+        for (var i = 0; i < solution.Length; i++) {
+          // in case we didn't make an improvement this round and arrived at the index of the last improvement
+          // break means we don't need to try the remaining moves again as they have brought no improvement
+          if (!improved && lastImp == i) break;
+          var idx = order[i];
+          if (subspace != null && !subspace[idx]) continue;
+          // bitflip the solution
+          solution[idx] = !solution[idx];
+          var after = evalFunc(solution);
+          evaluations++;
+          if (IsBetter(maximization, after, quality)) {
+            steps++;
+            quality = after;
+            lastImp = i;
+            improved = true;
+          } else {
+            // undo the bitflip in case no improvement was made
+            solution[idx] = !solution[idx];
+          }
+          token.ThrowIfCancellationRequested();
+        }
+      } while (improved);
+      
+      return Tuple.Create(evaluations, steps);
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainer.cs	(revision 14420)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  [Item("Biased Univariate Model Trainer (binary)", "")]
+  [StorableClass]
+  public class BiasedModelTrainer<TContext> : BiasedModelTrainerOperator, IBinarySolutionModelTrainer<TContext>, IBinaryVectorOperator
+    where TContext : ISingleObjectivePopulationContext<BinaryVector>, ISolutionModelContext<BinaryVector>, IStochasticContext, IMaximizationContext {
+    
+    [StorableConstructor]
+    protected BiasedModelTrainer(bool deserializing) : base(deserializing) { }
+    protected BiasedModelTrainer(BiasedModelTrainer<TContext> original, Cloner cloner) : base(original, cloner) { }
+    public BiasedModelTrainer() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BiasedModelTrainer<TContext>(this, cloner);
+    }
+
+    public void TrainModel(TContext context) {
+      context.Model = Trainer.TrainBiased(ModelBias, context.Random, context.Maximization, context.Population.Select(x => x.Solution), context.Population.Select(x => x.Fitness));
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainerOperator.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainerOperator.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/BiasedModelTrainerOperator.cs	(revision 14420)
@@ -0,0 +1,94 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  [Item("Biased Univariate Model Trainer Operator (binary)", "")]
+  [StorableClass]
+  public class BiasedModelTrainerOperator : SingleSuccessorOperator, ISolutionModelTrainer<BinaryVector> {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public ILookupParameter<BoolValue> MaximizationParameter {
+      get { return (ILookupParameter<BoolValue>)Parameters["Maximization"]; }
+    }
+
+    public IScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+
+    public IScopeTreeLookupParameter<BinaryVector> SolutionParameter {
+      get { return (IScopeTreeLookupParameter<BinaryVector>)Parameters["Solution"]; }
+    }
+
+    public ILookupParameter<ISolutionModel<BinaryVector>> SamplingModelParameter {
+      get { return (ILookupParameter<ISolutionModel<BinaryVector>>)Parameters["SamplingModel"]; }
+    }
+
+    private IValueParameter<EnumValue<ModelBiasOptions>> ModelBiasParameter {
+      get { return (IValueParameter<EnumValue<ModelBiasOptions>>)Parameters["ModelBias"]; }
+    }
+
+    public ModelBiasOptions ModelBias {
+      get { return ModelBiasParameter.Value.Value; }
+      set { ModelBiasParameter.Value.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected BiasedModelTrainerOperator(bool deserializing) : base(deserializing) { }
+    protected BiasedModelTrainerOperator(BiasedModelTrainerOperator original, Cloner cloner) : base(original, cloner) { }
+    public BiasedModelTrainerOperator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new LookupParameter<BoolValue>("Maximization", "Whether to maximize fitness or minimize it (only used when bias is not 'None')."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The solution quality (only used when bias is not 'None')."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Solution", "The binary vectors that are used to create the sampling model."));
+      Parameters.Add(new LookupParameter<ISolutionModel<BinaryVector>>("SamplingModel", "The model that can be used to sample new solutions."));
+      Parameters.Add(new ValueParameter<EnumValue<ModelBiasOptions>>("ModelBias",
+@"What kind of bias should be used when creating the model, e.g. 
+no bias (all solutions are considered equally), rank-based bias 
+(higher ranked solutions contribute more), or fitness-based bias 
+(fitness proportional bias)", new EnumValue<ModelBiasOptions>(ModelBiasOptions.Rank)));
+
+      SolutionParameter.ActualName = "BinaryVector";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BiasedModelTrainerOperator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      SamplingModelParameter.ActualValue = Trainer.TrainBiased(ModelBias, RandomParameter.ActualValue,
+        MaximizationParameter.ActualValue.Value, SolutionParameter.ActualValue, QualityParameter.ActualValue.Select(x => x.Value));
+      return base.Apply();
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/Trainer.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/Trainer.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/Trainer.cs	(revision 14420)
@@ -0,0 +1,47 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization.SolutionModel;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  public enum ModelBiasOptions { Rank, Fitness }
+
+  public static class Trainer {
+    public static ISolutionModel<BinaryVector> TrainBiased(ModelBiasOptions modelBias, IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      switch (modelBias) {
+        case ModelBiasOptions.Rank:
+          return UnivariateModel.CreateWithRankBias(random, maximization, population, qualities);
+        case ModelBiasOptions.Fitness:
+          return UnivariateModel.CreateWithFitnessBias(random, maximization, population, qualities);
+        default:
+          throw new InvalidOperationException(string.Format("Unknown bias option {0}", modelBias));
+      }
+    }
+
+    public static ISolutionModel<BinaryVector> TrainUnbiased(IRandom random, IEnumerable<BinaryVector> population) {
+      return UnivariateModel.CreateWithoutBias(random, population);
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainer.cs	(revision 14420)
@@ -0,0 +1,49 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  [Item("Uniased Univariate Model Trainer (binary)", "")]
+  [StorableClass]
+  public class UnbiasedModelTrainer<TContext> : UnbiasedModelTrainerOperator, IBinarySolutionModelTrainer<TContext>
+    where TContext : ISolutionModelContext<BinaryVector>, IPopulationContext<BinaryVector>, IStochasticContext {
+    
+    [StorableConstructor]
+    protected UnbiasedModelTrainer(bool deserializing) : base(deserializing) { }
+    protected UnbiasedModelTrainer(UnbiasedModelTrainer<TContext> original, Cloner cloner) : base(original, cloner) { }
+    public UnbiasedModelTrainer() { }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnbiasedModelTrainer<TContext>(this, cloner);
+    }
+
+    public void TrainModel(TContext context) {
+      context.Model = UnivariateModel.CreateWithoutBias(context.Random, context.Population.Select(x => x.Solution));
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainerOperator.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainerOperator.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnbiasedModelTrainerOperator.cs	(revision 14420)
@@ -0,0 +1,67 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+ 
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  [Item("Uniased Univariate Model Trainer Operator (binary)", "")]
+  [StorableClass]
+  public class UnbiasedModelTrainerOperator : SingleSuccessorOperator, ISolutionModelTrainer<BinaryVector> {
+
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    
+    public IScopeTreeLookupParameter<BinaryVector> SolutionParameter {
+      get { return (IScopeTreeLookupParameter<BinaryVector>)Parameters["Solution"]; }
+    }
+
+    public ILookupParameter<ISolutionModel<BinaryVector>> SamplingModelParameter {
+      get { return (ILookupParameter<ISolutionModel<BinaryVector>>)Parameters["SamplingModel"]; }
+    }
+
+    [StorableConstructor]
+    protected UnbiasedModelTrainerOperator(bool deserializing) : base(deserializing) { }
+    protected UnbiasedModelTrainerOperator(UnbiasedModelTrainerOperator original, Cloner cloner) : base(original, cloner) { }
+    public UnbiasedModelTrainerOperator() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator to use."));
+      Parameters.Add(new ScopeTreeLookupParameter<BinaryVector>("Solution", "The binary vectors that are used to create the sampling model."));
+      Parameters.Add(new LookupParameter<ISolutionModel<BinaryVector>>("SamplingModel", "The model that can be used to sample new solutions."));
+
+      SolutionParameter.ActualName = "BinaryVector";
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnbiasedModelTrainerOperator(this, cloner);
+    }
+    
+    public override IOperation Apply() {
+      SamplingModelParameter.ActualValue = UnivariateModel.CreateWithoutBias(RandomParameter.ActualValue, SolutionParameter.ActualValue);
+      return base.Apply();
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Binary/SolutionModel/Univariate/UnivariateSolutionModel.cs	(revision 14420)
@@ -0,0 +1,125 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Encodings.Binary.SolutionModel.Univariate {
+  [Item("Univariate solution model (binary)", "")]
+  [StorableClass]
+  public sealed class UnivariateModel : Item, ISolutionModel<BinaryVector> {
+    [Storable]
+    public DoubleArray Probabilities { get; set; }
+    [Storable]
+    public IRandom Random { get; set; }
+
+    [StorableConstructor]
+    private UnivariateModel(bool deserializing) : base(deserializing) { }
+    private UnivariateModel(UnivariateModel original, Cloner cloner)
+      : base(original, cloner) {
+      Probabilities = cloner.Clone(original.Probabilities);
+      Random = cloner.Clone(original.Random);
+    }
+    public UnivariateModel(IRandom random, int N) : this(random, Enumerable.Range(0, N).Select(x => 0.5).ToArray()) { }
+    public UnivariateModel(IRandom random, double[] probabilities) {
+      Probabilities = new DoubleArray(probabilities);
+      Random = random;
+    }
+    public UnivariateModel(IRandom random, DoubleArray probabilties) {
+      Probabilities = probabilties;
+      Random = random;
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new UnivariateModel(this, cloner);
+    }
+
+    public BinaryVector Sample() {
+      var vec = new BinaryVector(Probabilities.Length);
+      for (var i = 0; i < Probabilities.Length; i++)
+        vec[i] = Random.NextDouble() < Probabilities[i];
+      return vec;
+    }
+
+    public static ISolutionModel<BinaryVector> CreateWithoutBias(IRandom random, IEnumerable<BinaryVector> population) {
+      double[] model = null;
+      var popSize = 0;
+      foreach (var p in population) {
+        popSize++;
+        if (model == null) model = new double[p.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (p[x]) model[x]++;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 1.0 / popSize;
+      for (var x = 0; x < model.Length; x++) {
+        model[x] *= factor;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    public static ISolutionModel<BinaryVector> CreateWithRankBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var popSize = 0;
+
+      double[] model = null;
+      var pop = population.Zip(qualities, (b, q) => new { Solution = b, Fitness = q });
+      foreach (var ind in maximization ? pop.OrderBy(x => x.Fitness) : pop.OrderByDescending(x => x.Fitness)) {
+        // from worst to best, worst solution has 1 vote, best solution N votes
+        popSize++;
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += popSize;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      // normalize to [0;1]
+      var factor = 2.0 / (popSize + 1);
+      for (var i = 0; i < model.Length; i++) {
+        model[i] *= factor / popSize;
+      }
+      return new UnivariateModel(random, model);
+    }
+
+    public static ISolutionModel<BinaryVector> CreateWithFitnessBias(IRandom random, bool maximization, IEnumerable<BinaryVector> population, IEnumerable<double> qualities) {
+      var proportions = RandomEnumerable.PrepareProportional(qualities, true, !maximization);
+      var factor = 1.0 / proportions.Sum();
+      double[] model = null;
+      foreach (var ind in population.Zip(proportions, (p, q) => new { Solution = p, Proportion = q })) {
+        if (model == null) model = new double[ind.Solution.Length];
+        for (var x = 0; x < model.Length; x++) {
+          if (ind.Solution[x]) model[x] += ind.Proportion * factor;
+        }
+      }
+      if (model == null) throw new ArgumentException("Cannot train model from empty population.");
+      return new UnivariateModel(random, model);
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/HeuristicLab.Algorithms.MemPR-3.3.csproj	(revision 14420)
@@ -0,0 +1,194 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{9D274421-6332-4FBC-AAE4-467ACE27C368}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Algorithms.MemPR</RootNamespace>
+    <AssemblyName>HeuristicLab.Algorithms.MemPR-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\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>..\..\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>..\..\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>..\..\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>..\..\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>..\..\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="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Drawing" />
+    <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="Binary\BinaryMemPR.cs" />
+    <Compile Include="Binary\BinaryMemPRContext.cs" />
+    <Compile Include="Binary\BinarySolutionSubspace.cs" />
+    <Compile Include="Binary\LocalSearch\ExhaustiveBitflipSubspace.cs" />
+    <Compile Include="Binary\LocalSearch\ExhaustiveBitflip.cs" />
+    <Compile Include="Binary\LocalSearch\ExhaustiveBitflipOperator.cs" />
+    <Compile Include="Binary\LocalSearch\Heuristic.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\BiasedModelTrainerOperator.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\Trainer.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\UnbiasedModelTrainerOperator.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\UnivariateSolutionModel.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\BiasedModelTrainer.cs" />
+    <Compile Include="Binary\SolutionModel\Univariate\UnbiasedModelTrainer.cs" />
+    <Compile Include="Optimization\Interfaces.cs" />
+    <Compile Include="MemPRAlgorithm.cs" />
+    <Compile Include="SingleObjectiveSolutionScope.cs" />
+    <Compile Include="MemPRContext.cs" />
+    <Compile Include="Plugin.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Util\CkMeans1D.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
+      <Project>{887425b4-4348-49ed-a457-b7d2c26ddbf9}</Project>
+      <Name>HeuristicLab.Analysis-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
+      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
+      <Name>HeuristicLab.Collections-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj">
+      <Project>{0e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>
+      <Name>HeuristicLab.Common.Resources-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj">
+      <Project>{a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>
+      <Name>HeuristicLab.Common-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj">
+      <Project>{c36bd924-a541-4a00-afa8-41701378ddc5}</Project>
+      <Name>HeuristicLab.Core-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj">
+      <Project>{bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>
+      <Name>HeuristicLab.Data-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Encodings.BinaryVectorEncoding\3.3\HeuristicLab.Encodings.BinaryVectorEncoding-3.3.csproj">
+      <Project>{66d249c3-a01d-42a8-82a2-919bc8ec3d83}</Project>
+      <Name>HeuristicLab.Encodings.BinaryVectorEncoding-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Operators\3.3\HeuristicLab.Operators-3.3.csproj">
+      <Project>{23da7ff4-d5b8-41b6-aa96-f0561d24f3ee}</Project>
+      <Name>HeuristicLab.Operators-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj">
+      <Project>{14ab8d24-25bc-400c-a846-4627aa945192}</Project>
+      <Name>HeuristicLab.Optimization-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Parameters\3.3\HeuristicLab.Parameters-3.3.csproj">
+      <Project>{56f9106a-079f-4c61-92f6-86a84c2d84b7}</Project>
+      <Name>HeuristicLab.Parameters-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Persistence\3.3\HeuristicLab.Persistence-3.3.csproj">
+      <Project>{102bc7d3-0ef9-439c-8f6d-96ff0fdb8e1b}</Project>
+      <Name>HeuristicLab.Persistence-3.3</Name>
+      <Private>False</Private>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj">
+      <Project>{94186a6a-5176-4402-ae83-886557b53cca}</Project>
+      <Name>HeuristicLab.PluginInfrastructure-3.3</Name>
+      <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>
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRAlgorithm.cs	(revision 14420)
@@ -0,0 +1,733 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Threading;
+using HeuristicLab.Algorithms.MemPR.Util;
+using HeuristicLab.Analysis;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.LocalSearch;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MemPR {
+  [Item("MemPR Algorithm", "Base class for MemPR algorithms")]
+  [StorableClass]
+  public abstract class MemPRAlgorithm<TSolution, TContext, TSolutionContext> : BasicAlgorithm, INotifyPropertyChanged
+      where TSolution : class, IItem
+      where TContext : MemPRContext<TSolution, TContext, TSolutionContext>, new()
+      where TSolutionContext : SingleSolutionMemPRContext<TSolution, TContext, TSolutionContext> {
+    private const double MutationProbabilityMagicConst = 0.1;
+
+    public override Type ProblemType {
+      get { return typeof(ISingleObjectiveHeuristicOptimizationProblem); }
+    }
+
+    public new ISingleObjectiveHeuristicOptimizationProblem Problem {
+      get { return (ISingleObjectiveHeuristicOptimizationProblem)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    protected bool Maximization {
+      get {
+        return Problem != null && Problem.MaximizationParameter is IValueParameter<BoolValue>
+          && ((IValueParameter<BoolValue>)Problem.MaximizationParameter).Value.Value;
+      }
+    }
+
+    protected string QualityName {
+      get { return Problem != null && Problem.Evaluator != null ? Problem.Evaluator.QualityParameter.ActualName : null; }
+    }
+
+    public int? MaximumEvaluations {
+      get {
+        var val = ((OptionalValueParameter<IntValue>)Parameters["MaximumEvaluations"]).Value;
+        return val != null ? val.Value : (int?)null;
+      }
+      set {
+        var param = (OptionalValueParameter<IntValue>)Parameters["MaximumEvaluations"];
+        param.Value = value.HasValue ? new IntValue(value.Value) : null;
+      }
+    }
+
+    public TimeSpan? MaximumExecutionTime {
+      get {
+        var val = ((OptionalValueParameter<TimeSpanValue>)Parameters["MaximumExecutionTime"]).Value;
+        return val != null ? val.Value : (TimeSpan?)null;
+      }
+      set {
+        var param = (OptionalValueParameter<TimeSpanValue>)Parameters["MaximumExecutionTime"];
+        param.Value = value.HasValue ? new TimeSpanValue(value.Value) : null;
+      }
+    }
+
+    public double? TargetQuality {
+      get {
+        var val = ((OptionalValueParameter<DoubleValue>)Parameters["TargetQuality"]).Value;
+        return val != null ? val.Value : (double?)null;
+      }
+      set {
+        var param = (OptionalValueParameter<DoubleValue>)Parameters["TargetQuality"];
+        param.Value = value.HasValue ? new DoubleValue(value.Value) : null;
+      }
+    }
+
+    protected FixedValueParameter<IntValue> MaximumPopulationSizeParameter {
+      get { return ((FixedValueParameter<IntValue>)Parameters["MaximumPopulationSize"]); }
+    }
+    public int MaximumPopulationSize {
+      get { return MaximumPopulationSizeParameter.Value.Value; }
+      set { MaximumPopulationSizeParameter.Value.Value = value; }
+    }
+
+    public bool SetSeedRandomly {
+      get { return ((FixedValueParameter<BoolValue>)Parameters["SetSeedRandomly"]).Value.Value; }
+      set { ((FixedValueParameter<BoolValue>)Parameters["SetSeedRandomly"]).Value.Value = value; }
+    }
+
+    public int Seed {
+      get { return ((FixedValueParameter<IntValue>)Parameters["Seed"]).Value.Value; }
+      set { ((FixedValueParameter<IntValue>)Parameters["Seed"]).Value.Value = value; }
+    }
+
+    public IAnalyzer Analyzer {
+      get { return ((ValueParameter<IAnalyzer>)Parameters["Analyzer"]).Value; }
+      set { ((ValueParameter<IAnalyzer>)Parameters["Analyzer"]).Value = value; }
+    }
+
+    public IConstrainedValueParameter<ISolutionModelTrainer<TSolution, TContext>> SolutionModelTrainerParameter {
+      get { return (IConstrainedValueParameter<ISolutionModelTrainer<TSolution, TContext>>)Parameters["SolutionModelTrainer"]; }
+    }
+
+    public IConstrainedValueParameter<ILocalSearch<TSolution, TSolutionContext>> LocalSearchParameter {
+      get { return (IConstrainedValueParameter<ILocalSearch<TSolution, TSolutionContext>>)Parameters["LocalSearch"]; }
+    }
+
+    [Storable]
+    private TContext context;
+    public TContext Context {
+      get { return context; }
+      protected set {
+        if (context == value) return;
+        context = value;
+        OnPropertyChanged("State");
+      }
+    }
+
+    [Storable]
+    private BestAverageWorstQualityAnalyzer qualityAnalyzer;
+
+    [StorableConstructor]
+    protected MemPRAlgorithm(bool deserializing) : base(deserializing) { }
+    protected MemPRAlgorithm(MemPRAlgorithm<TSolution, TContext, TSolutionContext> original, Cloner cloner) : base(original, cloner) {
+      context = cloner.Clone(original.context);
+      qualityAnalyzer = cloner.Clone(original.qualityAnalyzer);
+      RegisterEventHandlers();
+    }
+    protected MemPRAlgorithm() {
+      Parameters.Add(new ValueParameter<IAnalyzer>("Analyzer", "The analyzer to apply to the population.", new MultiAnalyzer()));
+      Parameters.Add(new FixedValueParameter<IntValue>("MaximumPopulationSize", "The maximum size of the population that is evolved.", new IntValue(20)));
+      Parameters.Add(new OptionalValueParameter<IntValue>("MaximumEvaluations", "The maximum number of solution evaluations."));
+      Parameters.Add(new OptionalValueParameter<TimeSpanValue>("MaximumExecutionTime", "The maximum runtime.", new TimeSpanValue(TimeSpan.FromMinutes(1))));
+      Parameters.Add(new OptionalValueParameter<DoubleValue>("TargetQuality", "The target quality at which the algorithm terminates."));
+      Parameters.Add(new FixedValueParameter<BoolValue>("SetSeedRandomly", "Whether each run of the algorithm should be conducted with a new random seed.", new BoolValue(true)));
+      Parameters.Add(new FixedValueParameter<IntValue>("Seed", "The random number seed that is used in case SetSeedRandomly is false.", new IntValue(0)));
+      Parameters.Add(new ConstrainedValueParameter<ISolutionModelTrainer<TSolution, TContext>>("SolutionModelTrainer", "The object that creates a solution model that can be sampled."));
+      Parameters.Add(new ConstrainedValueParameter<ILocalSearch<TSolution, TSolutionContext>>("LocalSearch", "The local search operator to use."));
+
+      qualityAnalyzer = new BestAverageWorstQualityAnalyzer();
+      RegisterEventHandlers();
+    }
+
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterEventHandlers();
+    }
+
+    private void RegisterEventHandlers() {
+      MaximumPopulationSizeParameter.Value.ValueChanged += MaximumPopulationSizeOnChanged;
+    }
+
+    private void MaximumPopulationSizeOnChanged(object sender, EventArgs eventArgs) {
+      if (ExecutionState == ExecutionState.Started || ExecutionState == ExecutionState.Paused)
+        throw new InvalidOperationException("Cannot change maximum population size before algorithm finishes.");
+      Prepare();
+    }
+
+    protected override void OnProblemChanged() {
+      base.OnProblemChanged();
+      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;
+
+      var multiAnalyzer = Analyzer as MultiAnalyzer;
+      if (multiAnalyzer != null) {
+        multiAnalyzer.Operators.Clear();
+        if (Problem != null) {
+          foreach (var analyzer in Problem.Operators.OfType<IAnalyzer>()) {
+            foreach (var param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+              param.Depth = 1;
+            multiAnalyzer.Operators.Add(analyzer, analyzer.EnabledByDefault);
+          }
+        }
+        multiAnalyzer.Operators.Add(qualityAnalyzer, qualityAnalyzer.EnabledByDefault);
+      }
+    }
+
+    public override void Prepare() {
+      base.Prepare();
+      Results.Clear();
+      Context = null;
+    }
+
+    protected virtual TContext CreateContext() {
+      return new TContext();
+    }
+
+    protected sealed override void Run(CancellationToken token) {
+      if (Context == null) {
+        Context = CreateContext();
+        if (SetSeedRandomly) Seed = new System.Random().Next();
+        Context.Random.Reset(Seed);
+        Context.Scope.Variables.Add(new Variable("Results", Results));
+        Context.Maximization = Maximization;
+      }
+
+      IExecutionContext context = null;
+      foreach (var item in Problem.ExecutionContextItems)
+        context = new Core.ExecutionContext(context, item, Context.Scope);
+      context = new Core.ExecutionContext(context, this, Context.Scope);
+      Context.Parent = context;
+
+      if (!Context.Initialized) {
+        // We initialize the population with two local optima
+        while (Context.PopulationCount < 2) {
+          var child = Create(token);
+          Context.HcSteps += HillClimb(child, token);
+          Context.AddToPopulation(child);
+          Analyze(token);
+          token.ThrowIfCancellationRequested();
+        }
+        Context.HcSteps /= 2;
+        Context.Initialized = true;
+      }
+
+      while (!Terminate()) {
+        Iterate(token);
+        Analyze(token);
+        token.ThrowIfCancellationRequested();
+      }
+    }
+
+    private void Iterate(CancellationToken token) {
+      var replaced = false;
+
+      var i1 = Context.Random.Next(Context.PopulationCount);
+      var i2 = Context.Random.Next(Context.PopulationCount);
+      while (i1 == i2) i2 = Context.Random.Next(Context.PopulationCount);
+
+      var p1 = Context.AtPopulation(i1);
+      var p2 = Context.AtPopulation(i2);
+
+      if (double.IsNaN(p1.Fitness)) Evaluate(p1, token);
+      if (double.IsNaN(p2.Fitness)) Evaluate(p2, token);
+
+      var parentDist = Dist(p1, p2);
+
+      ISingleObjectiveSolutionScope<TSolution> offspring = null;
+      int replPos = -1;
+
+      if (Context.Random.NextDouble() > parentDist) {
+        offspring = BreedAndImprove(p1, p2, token);
+        replPos = Replace(offspring, token);
+        if (replPos >= 0) {
+          replaced = true;
+          Context.ByBreeding++;
+        }
+      }
+
+      if (Context.Random.NextDouble() < parentDist) {
+        offspring = RelinkAndImprove(p1, p2, token);
+        replPos = Replace(offspring, token);
+        if (replPos >= 0) {
+          replaced = true;
+          Context.ByRelinking++;
+        }
+      }
+
+      offspring = PerformSampling(token);
+      replPos = Replace(offspring, token);
+      if (replPos >= 0) {
+        replaced = true;
+        Context.BySampling++;
+      }
+
+      if (!replaced) {
+        offspring = Create(token);
+        if (HillclimbingSuited(offspring)) {
+          HillClimb(offspring, token);
+          replPos = Replace(offspring, token);
+          if (replPos >= 0) {
+            Context.ByHillclimbing++;
+            replaced = true;
+          }
+        } else {
+          offspring = (SingleObjectiveSolutionScope<TSolution>)Context.AtPopulation(Context.Random.Next(Context.PopulationCount)).Clone();
+          Mutate(offspring, token);
+          PerformTabuWalk(offspring, Context.HcSteps, token);
+          replPos = Replace(offspring, token);
+          if (replPos >= 0) {
+            Context.ByTabuwalking++;
+            replaced = true;
+          }
+        }
+      }
+      Context.Iterations++;
+    }
+
+    protected void Analyze(CancellationToken token) {
+      IResult res;
+      if (!Results.TryGetValue("EvaluatedSolutions", out res))
+        Results.Add(new Result("EvaluatedSolutions", new IntValue(Context.EvaluatedSolutions)));
+      else ((IntValue)res.Value).Value = Context.EvaluatedSolutions;
+      if (!Results.TryGetValue("Iterations", out res))
+        Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+      else ((IntValue)res.Value).Value = Context.Iterations;
+      if (!Results.TryGetValue("ByBreeding", out res))
+        Results.Add(new Result("ByBreeding", new IntValue(Context.ByBreeding)));
+      else ((IntValue)res.Value).Value = Context.ByBreeding;
+      if (!Results.TryGetValue("ByRelinking", out res))
+        Results.Add(new Result("ByRelinking", new IntValue(Context.ByRelinking)));
+      else ((IntValue)res.Value).Value = Context.ByRelinking;
+      if (!Results.TryGetValue("BySampling", out res))
+        Results.Add(new Result("BySampling", new IntValue(Context.BySampling)));
+      else ((IntValue)res.Value).Value = Context.BySampling;
+      if (!Results.TryGetValue("ByHillclimbing", out res))
+        Results.Add(new Result("ByHillclimbing", new IntValue(Context.ByHillclimbing)));
+      else ((IntValue)res.Value).Value = Context.ByHillclimbing;
+      if (!Results.TryGetValue("ByTabuwalking", out res))
+        Results.Add(new Result("ByTabuwalking", new IntValue(Context.ByTabuwalking)));
+      else ((IntValue)res.Value).Value = Context.ByTabuwalking;
+
+      var sp = new ScatterPlot("Parent1 vs Offspring", "");
+      sp.Rows.Add(new ScatterPlotDataRow("corr", "", Context.BreedingStat.Select(x => new Point2D<double>(x.Item1, x.Item3))) { VisualProperties = { PointSize = 6 }});
+      if (!Results.TryGetValue("BreedingStat1", out res)) {
+        Results.Add(new Result("BreedingStat1", sp));
+      } else res.Value = sp;
+
+      sp = new ScatterPlot("Parent2 vs Offspring", "");
+      sp.Rows.Add(new ScatterPlotDataRow("corr", "", Context.BreedingStat.Select(x => new Point2D<double>(x.Item2, x.Item3))) { VisualProperties = { PointSize = 6 } });
+      if (!Results.TryGetValue("BreedingStat2", out res)) {
+        Results.Add(new Result("BreedingStat2", sp));
+      } else res.Value = sp;
+
+      sp = new ScatterPlot("Solution vs Local Optimum", "");
+      sp.Rows.Add(new ScatterPlotDataRow("corr", "", Context.HillclimbingStat.Select(x => new Point2D<double>(x.Item1, x.Item2))) { VisualProperties = { PointSize = 6 } });
+      if (!Results.TryGetValue("HillclimbingStat", out res)) {
+        Results.Add(new Result("HillclimbingStat", sp));
+      } else res.Value = sp;
+
+      sp = new ScatterPlot("Solution vs Tabu Walk", "");
+      sp.Rows.Add(new ScatterPlotDataRow("corr", "", Context.TabuwalkingStat.Select(x => new Point2D<double>(x.Item1, x.Item2))) { VisualProperties = { PointSize = 6 } });
+      if (!Results.TryGetValue("TabuwalkingStat", out res)) {
+        Results.Add(new Result("TabuwalkingStat", sp));
+      } else res.Value = sp;
+
+      RunOperator(Analyzer, Context.Scope, token);
+    }
+
+    protected int Replace(ISingleObjectiveSolutionScope<TSolution> child, CancellationToken token) {
+      if (double.IsNaN(child.Fitness)) Evaluate(child, token);
+
+      var popSize = MaximumPopulationSize;
+      if (Context.Population.All(p => !Eq(p, child))) {
+
+        if (Context.PopulationCount < popSize) {
+          Context.AddToPopulation(child);
+          return Context.PopulationCount - 1;
+        }
+        
+        // The set of replacement candidates consists of all solutions at least as good as the new one
+        var candidates = Context.Population.Select((p, i) => new { Index = i, Individual = p })
+                                         .Where(x => x.Individual.Fitness == child.Fitness
+                                           || IsBetter(child, x.Individual)).ToList();
+        if (candidates.Count == 0) return -1;
+
+        var repCand = -1;
+        var avgChildDist = 0.0;
+        var minChildDist = double.MaxValue;
+        var plateau = new List<int>();
+        var worstPlateau = -1;
+        var minAvgPlateauDist = double.MaxValue;
+        var minPlateauDist = double.MaxValue;
+        // If there are equally good solutions it is first tried to replace one of those
+        // The criteria for replacement is that the new solution has better average distance
+        // to all other solutions at this "plateau"
+        foreach (var c in candidates.Where(x => x.Individual.Fitness == child.Fitness)) {
+          var dist = Dist(c.Individual, child);
+          avgChildDist += dist;
+          if (dist < minChildDist) minChildDist = dist;
+          plateau.Add(c.Index);
+        }
+        if (plateau.Count > 2) {
+          avgChildDist /= plateau.Count;
+          foreach (var p in plateau) {
+            var avgDist = 0.0;
+            var minDist = double.MaxValue;
+            foreach (var q in plateau) {
+              if (p == q) continue;
+              var dist = Dist(Context.AtPopulation(p), Context.AtPopulation(q));
+              avgDist += dist;
+              if (dist < minDist) minDist = dist;
+            }
+
+            var d = Dist(Context.AtPopulation(p), child);
+            avgDist += d;
+            avgDist /= plateau.Count;
+            if (d < minDist) minDist = d;
+
+            if (minDist < minPlateauDist || (minDist == minPlateauDist && avgDist < avgChildDist)) {
+              minAvgPlateauDist = avgDist;
+              minPlateauDist = minDist;
+              worstPlateau = p;
+            }
+          }
+          if (minPlateauDist < minChildDist || (minPlateauDist == minChildDist && minAvgPlateauDist < avgChildDist))
+            repCand = worstPlateau;
+        }
+
+        if (repCand < 0) {
+          // If no solution at the same plateau were identified for replacement
+          // a worse solution with smallest distance is chosen
+          var minDist = double.MaxValue;
+          foreach (var c in candidates.Where(x => IsBetter(child, x.Individual))) {
+            var d = Dist(c.Individual, child);
+            if (d < minDist) {
+              minDist = d;
+              repCand = c.Index;
+            }
+          }
+        }
+
+        // If no replacement was identified, this can only mean that there are
+        // no worse solutions and those on the same plateau are all better
+        // stretched out than the new one
+        if (repCand < 0) return -1;
+        
+        Context.ReplaceAtPopulation(repCand, child);
+        return repCand;
+      }
+      return -1;
+    }
+
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    protected bool IsBetter(ISingleObjectiveSolutionScope<TSolution> a, ISingleObjectiveSolutionScope<TSolution> b) {
+      return IsBetter(a.Fitness, b.Fitness);
+    }
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    protected bool IsBetter(double a, double b) {
+      return double.IsNaN(b) && !double.IsNaN(a)
+        || Maximization && a > b
+        || !Maximization && a < b;
+    }
+    
+    protected abstract bool Eq(ISingleObjectiveSolutionScope<TSolution> a, ISingleObjectiveSolutionScope<TSolution> b);
+    protected abstract double Dist(ISingleObjectiveSolutionScope<TSolution> a, ISingleObjectiveSolutionScope<TSolution> b);
+    protected abstract ISingleObjectiveSolutionScope<TSolution> ToScope(TSolution code, double fitness = double.NaN);
+    protected abstract ISolutionSubspace CalculateSubspace(IEnumerable<TSolution> solutions, bool inverse = false);
+    protected virtual void Evaluate(ISingleObjectiveSolutionScope<TSolution> scope, CancellationToken token) {
+      Context.EvaluatedSolutions++;
+      var prob = Problem as ISingleObjectiveProblemDefinition;
+      if (prob != null) {
+        var ind = new SingleEncodingIndividual(prob.Encoding, scope);
+        scope.Fitness = prob.Evaluate(ind, Context.Random);
+      } else RunOperator(Problem.Evaluator, scope, token);
+      if (IsBetter(scope.Fitness, Context.BestQuality))
+        Context.BestQuality = scope.Fitness;
+    }
+
+    #region Create
+    protected abstract ISingleObjectiveSolutionScope<TSolution> Create(CancellationToken token);
+    #endregion
+
+    #region Improve
+    protected virtual int HillClimb(ISingleObjectiveSolutionScope<TSolution> scope, CancellationToken token, ISolutionSubspace subspace = null) {
+      if (double.IsNaN(scope.Fitness)) Evaluate(scope, token);
+      var before = scope.Fitness;
+      var lscontext = Context.CreateSingleSolutionContext(scope);
+      LocalSearchParameter.Value.Optimize(lscontext);
+      var after = scope.Fitness;
+      Context.HillclimbingStat.Add(Tuple.Create(before, after));
+      return lscontext.Iterations;
+    }
+
+    protected virtual void PerformTabuWalk(ISingleObjectiveSolutionScope<TSolution> scope, int steps, CancellationToken token, ISolutionSubspace subspace = null) {
+      if (double.IsNaN(scope.Fitness)) Evaluate(scope, token);
+      var before = scope.Fitness;
+      var newScope = (ISingleObjectiveSolutionScope<TSolution>)scope.Clone();
+      TabuWalk(newScope, steps, token, subspace);
+      Context.TabuwalkingStat.Add(Tuple.Create(before, newScope.Fitness));
+      if (IsBetter(newScope, scope) || (newScope.Fitness == scope.Fitness && Dist(newScope, scope) > 0))
+        scope.Adopt(newScope);
+    }
+    protected abstract void TabuWalk(ISingleObjectiveSolutionScope<TSolution> scope, int steps, CancellationToken token, ISolutionSubspace subspace = null);
+    protected virtual void TabuClimb(ISingleObjectiveSolutionScope<TSolution> scope, int steps, CancellationToken token, ISolutionSubspace subspace = null) {
+      if (double.IsNaN(scope.Fitness)) Evaluate(scope, token);
+      var before = scope.Fitness;
+      var newScope = (ISingleObjectiveSolutionScope<TSolution>)scope.Clone();
+      TabuWalk(newScope, steps, token, subspace);
+      Context.TabuwalkingStat.Add(Tuple.Create(before, newScope.Fitness));
+      if (IsBetter(newScope, scope) || (newScope.Fitness == scope.Fitness && Dist(newScope, scope) > 0))
+        scope.Adopt(newScope);
+    }
+    #endregion
+    
+    #region Breed
+    protected virtual ISingleObjectiveSolutionScope<TSolution> PerformBreeding(CancellationToken token) {
+      if (Context.PopulationCount < 2) throw new InvalidOperationException("Cannot breed from population with less than 2 individuals.");
+      var i1 = Context.Random.Next(Context.PopulationCount);
+      var i2 = Context.Random.Next(Context.PopulationCount);
+      while (i1 == i2) i2 = Context.Random.Next(Context.PopulationCount);
+
+      var p1 = Context.AtPopulation(i1);
+      var p2 = Context.AtPopulation(i2);
+
+      if (double.IsNaN(p1.Fitness)) Evaluate(p1, token);
+      if (double.IsNaN(p2.Fitness)) Evaluate(p2, token);
+
+      return BreedAndImprove(p1, p2, token);
+    }
+
+    protected virtual ISingleObjectiveSolutionScope<TSolution> BreedAndImprove(ISingleObjectiveSolutionScope<TSolution> p1, ISingleObjectiveSolutionScope<TSolution> p2, CancellationToken token) {
+      var offspring = Cross(p1, p2, token);
+      var subspace = CalculateSubspace(new[] { p1.Solution, p2.Solution });
+      if (Context.Random.NextDouble() < MutationProbabilityMagicConst) {
+        Mutate(offspring, token, subspace); // mutate the solutions, especially to widen the sub-space
+      }
+      if (double.IsNaN(offspring.Fitness)) Evaluate(offspring, token);
+      Context.BreedingStat.Add(Tuple.Create(p1.Fitness, p2.Fitness, offspring.Fitness));
+      if ((IsBetter(offspring, p1) && IsBetter(offspring, p2))
+        || Context.Population.Any(p => IsBetter(offspring, p))) return offspring;
+
+      if (HillclimbingSuited(offspring))
+        HillClimb(offspring, token, subspace); // perform hillclimb in the solution sub-space
+      return offspring;
+    }
+
+    protected abstract ISingleObjectiveSolutionScope<TSolution> Cross(ISingleObjectiveSolutionScope<TSolution> p1, ISingleObjectiveSolutionScope<TSolution> p2, CancellationToken token);
+    protected abstract void Mutate(ISingleObjectiveSolutionScope<TSolution> offspring, CancellationToken token, ISolutionSubspace subspace = null);
+    #endregion
+
+    #region Relink
+    protected virtual ISingleObjectiveSolutionScope<TSolution> PerformRelinking(CancellationToken token) {
+      if (Context.PopulationCount < 2) throw new InvalidOperationException("Cannot breed from population with less than 2 individuals.");
+      var i1 = Context.Random.Next(Context.PopulationCount);
+      var i2 = Context.Random.Next(Context.PopulationCount);
+      while (i1 == i2) i2 = Context.Random.Next(Context.PopulationCount);
+
+      var p1 = Context.AtPopulation(i1);
+      var p2 = Context.AtPopulation(i2);
+
+      if (double.IsNaN(p1.Fitness)) Evaluate(p1, token);
+      if (double.IsNaN(p2.Fitness)) Evaluate(p2, token);
+
+      return RelinkAndImprove(p1, p2, token);
+    }
+
+    protected virtual ISingleObjectiveSolutionScope<TSolution> RelinkAndImprove(ISingleObjectiveSolutionScope<TSolution> a, ISingleObjectiveSolutionScope<TSolution> b, CancellationToken token) {
+      var child = Relink(a, b, token);
+      if (IsBetter(child, a) && IsBetter(child, b)) return child;
+
+      var dist1 = Dist(child, a);
+      var dist2 = Dist(child, b);
+      if (dist1 > 0 && dist2 > 0) {
+        var subspace = CalculateSubspace(new[] { a.Solution, b.Solution }, inverse: true);
+        if (HillclimbingSuited(child)) {
+          HillClimb(child, token, subspace);
+        }
+      }
+      return child;
+    }
+
+    protected abstract ISingleObjectiveSolutionScope<TSolution> Relink(ISingleObjectiveSolutionScope<TSolution> a, ISingleObjectiveSolutionScope<TSolution> b, CancellationToken token);
+    #endregion
+
+    #region Sample
+    protected virtual ISingleObjectiveSolutionScope<TSolution> PerformSampling(CancellationToken token) {
+      SolutionModelTrainerParameter.Value.TrainModel(Context);
+      var sample = ToScope(Context.Model.Sample());
+      if (Context.Population.Any(p => IsBetter(sample, p) || sample.Fitness == p.Fitness)) return sample;
+
+      if (HillclimbingSuited(sample)) {
+        var subspace = CalculateSubspace(Context.Population.Select(x => x.Solution));
+        HillClimb(sample, token, subspace);
+      }
+      return sample;
+    }
+    #endregion
+
+    protected bool HillclimbingSuited(ISingleObjectiveSolutionScope<TSolution> scope) {
+      return Context.Random.NextDouble() < ProbabilityAccept(scope, Context.HillclimbingStat);
+    }
+    protected bool HillclimbingSuited(double startingFitness) {
+      return Context.Random.NextDouble() < ProbabilityAccept(startingFitness, Context.HillclimbingStat);
+    }
+    protected bool TabuwalkingSuited(ISingleObjectiveSolutionScope<TSolution> scope) {
+      return Context.Random.NextDouble() < ProbabilityAccept(scope, Context.TabuwalkingStat);
+    }
+    protected bool TabuwalkingSuited(double startingFitness) {
+      return Context.Random.NextDouble() < ProbabilityAccept(startingFitness, Context.TabuwalkingStat);
+    }
+
+    protected double ProbabilityAccept(ISingleObjectiveSolutionScope<TSolution> scope, IList<Tuple<double, double>> data) {
+      if (double.IsNaN(scope.Fitness)) Evaluate(scope, CancellationToken.None);
+      return ProbabilityAccept(scope.Fitness, data);
+    }
+    protected double ProbabilityAccept(double startingFitness, IList<Tuple<double, double>> data) {
+      if (data.Count < 10) return 1.0;
+      int[] clusterValues;
+      var centroids = CkMeans1D.Cluster(data.Select(x => x.Item1).ToArray(), 2, out clusterValues);
+      var cluster = Math.Abs(startingFitness - centroids.First().Key) < Math.Abs(startingFitness - centroids.Last().Key) ? centroids.First().Value : centroids.Last().Value;
+
+      var samples = 0;
+      double meanStart = 0, meanStartOld = 0, meanEnd = 0, meanEndOld = 0;
+      double varStart = 0, varStartOld = 0, varEnd = 0, varEndOld = 0;
+      for (var i = 0; i < data.Count; i++) {
+        if (clusterValues[i] != cluster) continue;
+
+        samples++;
+        var x = data[i].Item1;
+        var y = data[i].Item2;
+
+        if (samples == 1) {
+          meanStartOld = x;
+          meanEndOld = y;
+        } else {
+          meanStart = meanStartOld + (x - meanStartOld) / samples;
+          meanEnd = meanEndOld + (x - meanEndOld) / samples;
+          varStart = varStartOld + (x - meanStartOld) * (x - meanStart) / (samples - 1);
+          varEnd = varEndOld + (x - meanEndOld) * (x - meanEnd) / (samples - 1);
+
+          meanStartOld = meanStart;
+          meanEndOld = meanEnd;
+          varStartOld = varStart;
+          varEndOld = varEnd;
+        }
+      }
+      if (samples < 5) return 1.0;
+      var cov = data.Select((v, i) => new { Index = i, Value = v }).Where(x => clusterValues[x.Index] == cluster).Select(x => x.Value).Sum(x => (x.Item1 - meanStart) * (x.Item2 - meanEnd)) / data.Count;
+
+      var biasedMean = meanEnd + cov / varStart * (startingFitness - meanStart);
+      var biasedStdev = Math.Sqrt(varEnd - (cov * cov) / varStart);
+
+      if (Maximization) {
+        var goal = Context.Population.Min(x => x.Fitness);
+        var z = (goal - biasedMean) / biasedStdev;
+        return 1.0 - Phi(z); // P(X >= z)
+      } else {
+        var goal = Context.Population.Max(x => x.Fitness);
+        var z = (goal - biasedMean) / biasedStdev;
+        return Phi(z); // P(X <= z)
+      }
+    }
+
+    protected virtual bool Terminate() {
+      return MaximumEvaluations.HasValue && Context.EvaluatedSolutions >= MaximumEvaluations.Value
+        || MaximumExecutionTime.HasValue && ExecutionTime >= MaximumExecutionTime.Value
+        || TargetQuality.HasValue && (Maximization && Context.BestQuality >= TargetQuality.Value
+                                  || !Maximization && Context.BestQuality <= TargetQuality.Value);
+    }
+
+    public event PropertyChangedEventHandler PropertyChanged;
+    protected void OnPropertyChanged(string property) {
+      var handler = PropertyChanged;
+      if (handler != null) handler(this, new PropertyChangedEventArgs(property));
+    }
+
+    #region Engine Helper
+    protected void RunOperator(IOperator op, IScope scope, CancellationToken cancellationToken) {
+      var stack = new Stack<IOperation>();
+      stack.Push(Context.CreateChildOperation(op, scope));
+
+      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);
+        }
+      }
+    }
+    #endregion
+
+    #region Math Helper
+    // normal distribution CDF (left of x) for N(0;1) standard normal distribution
+    // from http://www.johndcook.com/blog/csharp_phi/
+    // license: "This code is in the public domain. Do whatever you want with it, no strings attached."
+    // added: 2016-11-19 21:46 CET
+    protected static double Phi(double x) {
+      // constants
+      double a1 = 0.254829592;
+      double a2 = -0.284496736;
+      double a3 = 1.421413741;
+      double a4 = -1.453152027;
+      double a5 = 1.061405429;
+      double p = 0.3275911;
+
+      // Save the sign of x
+      int sign = 1;
+      if (x < 0)
+        sign = -1;
+      x = Math.Abs(x) / Math.Sqrt(2.0);
+
+      // A&S formula 7.1.26
+      double t = 1.0 / (1.0 + p * x);
+      double y = 1.0 - (((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t * Math.Exp(-x * x);
+
+      return 0.5 * (1.0 + sign * y);
+    }
+    #endregion
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRContext.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRContext.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/MemPRContext.cs	(revision 14420)
@@ -0,0 +1,347 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+using HeuristicLab.Optimization.SolutionModel;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Random;
+
+namespace HeuristicLab.Algorithms.MemPR {
+  [Item("MemPRContext", "Abstract base class for MemPR contexts.")]
+  [StorableClass]
+  public abstract class MemPRContext<TSolution, TContext, TSolutionContext> : ParameterizedNamedItem,
+      ISingleObjectivePopulationContext<TSolution>, ISolutionModelContext<TSolution>, IStochasticContext,
+      IMaximizationContext, IEvaluatedSolutionsContext
+      where TSolution : class, IItem
+      where TContext : MemPRContext<TSolution, TContext, TSolutionContext>
+      where TSolutionContext : SingleSolutionMemPRContext<TSolution, TContext, TSolutionContext> {
+
+    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 IValueParameter<BoolValue> maximization;
+    public bool Maximization {
+      get { return maximization.Value.Value; }
+      set { maximization.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<BoolValue> initialized;
+    public bool Initialized {
+      get { return initialized.Value.Value; }
+      set { initialized.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> iterations;
+    public int Iterations {
+      get { return iterations.Value.Value; }
+      set { iterations.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<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<IntValue> hcSteps;
+    public int HcSteps {
+      get { return hcSteps.Value.Value; }
+      set { hcSteps.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> byBreeding;
+    public int ByBreeding {
+      get { return byBreeding.Value.Value; }
+      set { byBreeding.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> byRelinking;
+    public int ByRelinking {
+      get { return byRelinking.Value.Value; }
+      set { byRelinking.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> bySampling;
+    public int BySampling {
+      get { return bySampling.Value.Value; }
+      set { bySampling.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> byHillclimbing;
+    public int ByHillclimbing {
+      get { return byHillclimbing.Value.Value; }
+      set { byHillclimbing.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> byTabuwalking;
+    public int ByTabuwalking {
+      get { return byTabuwalking.Value.Value; }
+      set { byTabuwalking.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IRandom> random;
+    public IRandom Random {
+      get { return random.Value; }
+      set { random.Value = value; }
+    }
+
+    IEnumerable<IScope> IPopulationContext.Population {
+      get { return scope.SubScopes; }
+    }
+    
+    public IEnumerable<ISingleObjectiveSolutionScope<TSolution>> Population {
+      get { return scope.SubScopes.OfType<ISingleObjectiveSolutionScope<TSolution>>(); }
+    }
+    public void AddToPopulation(ISingleObjectiveSolutionScope<TSolution> solScope) {
+      scope.SubScopes.Add(solScope);
+    }
+    public void ReplaceAtPopulation(int index, ISingleObjectiveSolutionScope<TSolution> solScope) {
+      scope.SubScopes[index] = solScope;
+    }
+    public ISingleObjectiveSolutionScope<TSolution> AtPopulation(int index) {
+      return scope.SubScopes[index] as ISingleObjectiveSolutionScope<TSolution>;
+    }
+    public int PopulationCount {
+      get { return scope.SubScopes.Count; }
+    }
+
+    [Storable]
+    private List<Tuple<double, double, double>> breedingStat;
+    public List<Tuple<double, double, double>> BreedingStat {
+      get { return breedingStat; }
+    }
+    [Storable]
+    private List<Tuple<double, double>> hillclimbingStat;
+    public List<Tuple<double, double>> HillclimbingStat {
+      get { return hillclimbingStat; }
+    }
+    [Storable]
+    private List<Tuple<double, double>> tabuwalkingStat;
+    public List<Tuple<double, double>> TabuwalkingStat {
+      get { return tabuwalkingStat; }
+    }
+
+    [Storable]
+    public ISolutionModel<TSolution> Model { get; set; }
+
+    [StorableConstructor]
+    protected MemPRContext(bool deserializing) : base(deserializing) { }
+    protected MemPRContext(MemPRContext<TSolution, TContext, TSolutionContext> original, Cloner cloner)
+      : base(original, cloner) {
+      scope = cloner.Clone(original.scope);
+      maximization = cloner.Clone(original.maximization);
+      initialized = cloner.Clone(original.initialized);
+      iterations = cloner.Clone(original.iterations);
+      evaluatedSolutions = cloner.Clone(original.evaluatedSolutions);
+      bestQuality = cloner.Clone(original.bestQuality);
+      hcSteps = cloner.Clone(original.hcSteps);
+      byBreeding = cloner.Clone(original.byBreeding);
+      byRelinking = cloner.Clone(original.byRelinking);
+      bySampling = cloner.Clone(original.bySampling);
+      byHillclimbing = cloner.Clone(original.byHillclimbing);
+      byTabuwalking = cloner.Clone(original.byTabuwalking);
+      random = cloner.Clone(original.random);
+      breedingStat = original.breedingStat.Select(x => Tuple.Create(x.Item1, x.Item2, x.Item3)).ToList();
+      hillclimbingStat = original.hillclimbingStat.Select(x => Tuple.Create(x.Item1, x.Item2)).ToList();
+      tabuwalkingStat = original.tabuwalkingStat.Select(x => Tuple.Create(x.Item1, x.Item2)).ToList();
+
+      Model = cloner.Clone(original.Model);
+    }
+    public MemPRContext() : this("MemPRContext") { }
+    public MemPRContext(string name) : base(name) {
+      scope = new Scope("Global");
+
+      Parameters.Add(maximization = new ValueParameter<BoolValue>("Maximization", new BoolValue(false)));
+      Parameters.Add(initialized = new ValueParameter<BoolValue>("Initialized", new BoolValue(false)));
+      Parameters.Add(iterations = new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+      Parameters.Add(evaluatedSolutions = new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(bestQuality = new ValueParameter<DoubleValue>("BestQuality", new DoubleValue(double.NaN)));
+      Parameters.Add(hcSteps = new ValueParameter<IntValue>("HcSteps", new IntValue(0)));
+      Parameters.Add(byBreeding = new ValueParameter<IntValue>("ByBreeding", new IntValue(0)));
+      Parameters.Add(byRelinking = new ValueParameter<IntValue>("ByRelinking", new IntValue(0)));
+      Parameters.Add(bySampling = new ValueParameter<IntValue>("BySampling", new IntValue(0)));
+      Parameters.Add(byHillclimbing = new ValueParameter<IntValue>("ByHillclimbing", new IntValue(0)));
+      Parameters.Add(byTabuwalking = new ValueParameter<IntValue>("ByTabuwalking", new IntValue(0)));
+      Parameters.Add(random = new ValueParameter<IRandom>("Random", new MersenneTwister()));
+
+      breedingStat = new List<Tuple<double, double, double>>();
+      hillclimbingStat = new List<Tuple<double, double>>();
+      tabuwalkingStat = new List<Tuple<double, double>>();
+    }
+
+    public abstract TSolutionContext CreateSingleSolutionContext(ISingleObjectiveSolutionScope<TSolution> solution);
+
+    #region IExecutionContext members
+    public IAtomicOperation CreateOperation(IOperator op) {
+      return new ExecutionContext(this, op, Scope);
+    }
+
+    public IAtomicOperation CreateOperation(IOperator op, IScope s) {
+      return new ExecutionContext(this, op, s);
+    }
+
+    public IAtomicOperation CreateChildOperation(IOperator op) {
+      return new ExecutionContext(this, op, Scope);
+    }
+
+    public IAtomicOperation CreateChildOperation(IOperator op, IScope s) {
+      return new ExecutionContext(this, op, s);
+    }
+    #endregion
+
+    IEnumerable<ISolutionScope<TSolution>> IPopulationContext<TSolution>.Population {
+      get { return Population; }
+    }
+  }
+
+  [Item("SingleSolutionMemPRContext", "Abstract base class for single solution MemPR contexts.")]
+  [StorableClass]
+  public abstract class SingleSolutionMemPRContext<TSolution, TContext, TSolutionContext> : ParameterizedNamedItem,
+      ISingleObjectiveSolutionContext<TSolution>, IEvaluatedSolutionsContext,
+      IIterationsManipulationContext, IStochasticContext, IMaximizationContext
+      where TSolution : class, IItem
+      where TContext : MemPRContext<TSolution, TContext, TSolutionContext>
+      where TSolutionContext : SingleSolutionMemPRContext<TSolution, TContext, TSolutionContext> {
+
+    private TContext parent;
+    public IExecutionContext Parent {
+      get { return parent; }
+      set { throw new InvalidOperationException("Cannot set the parent of a single-solution context."); }
+    }
+
+    [Storable]
+    private ISingleObjectiveSolutionScope<TSolution> scope;
+    public IScope Scope {
+      get { return scope; }
+    }
+
+    IKeyedItemCollection<string, IParameter> IExecutionContext.Parameters {
+      get { return Parameters; }
+    }
+    
+    public bool Maximization {
+      get { return parent.Maximization; }
+    }
+
+    public IRandom Random {
+      get { return parent.Random; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> evaluatedSolutions;
+    public int EvaluatedSolutions {
+      get { return evaluatedSolutions.Value.Value; }
+      set { evaluatedSolutions.Value.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<IntValue> iterations;
+    public int Iterations {
+      get { return iterations.Value.Value; }
+      set { iterations.Value.Value = value; }
+    }
+
+    IScope ISolutionContext.Solution {
+      get { return scope; }
+    }
+
+    ISolutionScope<TSolution> ISolutionContext<TSolution>.Solution {
+      get { return scope; }
+    }
+
+    ISingleObjectiveSolutionScope<TSolution> ISingleObjectiveSolutionContext<TSolution>.Solution {
+      get { return scope; }
+    }
+
+    [StorableConstructor]
+    protected SingleSolutionMemPRContext(bool deserializing) : base(deserializing) { }
+    protected SingleSolutionMemPRContext(SingleSolutionMemPRContext<TSolution, TContext, TSolutionContext> original, Cloner cloner)
+      : base(original, cloner) {
+      scope = cloner.Clone(original.scope);
+      evaluatedSolutions = cloner.Clone(original.evaluatedSolutions);
+      iterations = cloner.Clone(original.iterations);
+    }
+    public SingleSolutionMemPRContext(TContext baseContext, ISingleObjectiveSolutionScope<TSolution> solution) {
+      parent = baseContext;
+      scope = solution;
+      
+      Parameters.Add(evaluatedSolutions = new ValueParameter<IntValue>("EvaluatedSolutions", new IntValue(0)));
+      Parameters.Add(iterations = new ValueParameter<IntValue>("Iterations", new IntValue(0)));
+    }
+
+    #region IExecutionContext members
+    public IAtomicOperation CreateOperation(IOperator op) {
+      return new ExecutionContext(this, op, Scope);
+    }
+
+    public IAtomicOperation CreateOperation(IOperator op, IScope s) {
+      return new ExecutionContext(this, op, s);
+    }
+
+    public IAtomicOperation CreateChildOperation(IOperator op) {
+      return new ExecutionContext(this, op, Scope);
+    }
+
+    public IAtomicOperation CreateChildOperation(IOperator op, IScope s) {
+      return new ExecutionContext(this, op, s);
+    }
+    #endregion
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Optimization/Interfaces.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Optimization/Interfaces.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Optimization/Interfaces.cs	(revision 14420)
@@ -0,0 +1,191 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using HeuristicLab.Algorithms.MemPR.Binary;
+using HeuristicLab.Core;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+
+/*************************************************
+ * ********************************************* *
+ *                    DATA                       *
+ * ********************************************* *
+ *************************************************/
+
+namespace HeuristicLab.Optimization.SolutionModel {
+
+  public interface ISolutionModel<TSolution> : IItem {
+    TSolution Sample();
+  }
+}
+
+namespace HeuristicLab.Optimization {
+
+  public interface ISolutionSubspace : IItem { }
+}
+
+/*************************************************
+   * ********************************************* *
+   *                  OPERATORS                    *
+   * ********************************************* *
+   *************************************************/
+
+namespace HeuristicLab.Optimization.SolutionModel {
+
+  public interface ISolutionModelTrainer<TSolution> : IOperator
+      where TSolution : class, IItem {
+    IScopeTreeLookupParameter<TSolution> SolutionParameter { get; }
+    ILookupParameter<ISolutionModel<TSolution>> SamplingModelParameter { get; }
+  }
+
+  public interface ISolutionModelTrainer<TSolution, TContext> : ISolutionModelTrainer<TSolution>
+      where TSolution : class, IItem
+      where TContext : ISolutionModelContext<TSolution> {
+
+    void TrainModel(TContext context);
+  }
+
+  public interface IBinarySolutionModelTrainer<TContext> : ISolutionModelTrainer<BinaryVector, TContext>
+      where TContext : ISolutionModelContext<BinaryVector> { }
+}
+
+namespace HeuristicLab.Optimization.LocalSearch {
+
+  public interface ILocalSearch<TSolution> : IOperator
+      where TSolution : class, IItem {
+    ILookupParameter<TSolution> SolutionParameter { get; }
+
+    Func<TSolution, double> EvaluateFunc { get; set; }
+  }
+
+  public interface ILocalSearch<TSolution, TContext> : ILocalSearch<TSolution>
+      where TSolution : class, IItem {
+
+    void Optimize(TContext context);
+  }
+
+  public interface IBinaryLocalSearch<TContext> : ILocalSearch<BinaryVector, TContext> {
+    
+  }
+
+}
+
+/*************************************************
+   * ********************************************* *
+   *                  CONTEXTS                     *
+   * ********************************************* *
+   *************************************************/
+
+namespace HeuristicLab.Optimization {
+  
+  public interface IStochasticContext : IExecutionContext {
+    IRandom Random { get; }
+  }
+
+  public interface IMaximizationContext : IExecutionContext {
+    bool Maximization { get; }
+  }
+
+  public interface IEvaluatedSolutionsContext : IExecutionContext {
+    int EvaluatedSolutions { get; set; }
+  }
+
+  public interface IIterationsContext : IExecutionContext {
+    int Iterations { get; }
+  }
+
+  public interface IIterationsManipulationContext : IIterationsContext {
+    new int Iterations { get; set; }
+  }
+
+  public interface IPopulationContext : IExecutionContext {
+    IEnumerable<IScope> Population { get; }
+  }
+
+  public interface IPopulationContext<TSolution> : IPopulationContext {
+    new IEnumerable<ISolutionScope<TSolution>> Population { get; }
+  }
+
+  public interface ISingleObjectivePopulationContext<TSolution> : IPopulationContext<TSolution> {
+    new IEnumerable<ISingleObjectiveSolutionScope<TSolution>> Population { get; }
+  }
+
+  public interface ISolutionContext : IExecutionContext {
+    IScope Solution { get; }
+  }
+
+  public interface ISolutionContext<TSolution> : ISolutionContext {
+    new ISolutionScope<TSolution> Solution { get; }
+  }
+
+  public interface ISingleObjectiveSolutionContext<TSolution> : ISolutionContext<TSolution> {
+    new ISingleObjectiveSolutionScope<TSolution> Solution { get; }
+  }
+
+  /* Probably a setter is not needed anyway, since there is Adopt() also
+  public interface ISolutionManipulationContext : ISolutionContext {
+    new IScope Solution { get; set; }
+  }
+
+  public interface ISolutionManipulationContext<TSolution> : ISolutionManipulationContext, ISolutionContext<TSolution> {
+    new ISolutionScope<TSolution> Solution { get; set; }
+  }
+
+  public interface ISingleObjectiveSolutionManipulationContext<TSolution> : ISolutionManipulationContext<TSolution>, ISingleObjectiveSolutionContext<TSolution> {
+    new ISingleObjectiveSolutionScope<TSolution> Solution { get; set; }
+  }
+  */
+
+  public interface ISolutionSubspaceContext : IExecutionContext {
+    ISolutionSubspace Subspace { get; }
+  }
+  public interface IBinarySolutionSubspaceContext : ISolutionSubspaceContext {
+    new BinarySolutionSubspace Subspace { get; }
+  }
+}
+
+namespace HeuristicLab.Optimization.SolutionModel {
+  public interface ISolutionModelContext<TSolution> : IExecutionContext {
+    ISolutionModel<TSolution> Model { get; set; }
+  }
+}
+
+
+/*************************************************
+   * ********************************************* *
+   *                   SCOPES                      *
+   * ********************************************* *
+   *************************************************/
+  
+namespace HeuristicLab.Core {
+  public interface ISolutionScope<TSolution> : IScope {
+    TSolution Solution { get; set; }
+
+    void Adopt(ISolutionScope<TSolution> orphan);
+  }
+
+  public interface ISingleObjectiveSolutionScope<TSolution> : ISolutionScope<TSolution> {
+    double Fitness { get; set; }
+
+    void Adopt(ISingleObjectiveSolutionScope<TSolution> orphan);
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Plugin.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Plugin.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Plugin.cs	(revision 14420)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Algorithms.MemPR {
+
+  [Plugin("HeuristicLab.Algorithms.MemPR", "Provides the MemPR (MEMetic Path Relinking) algorithm.", "3.3.14.0")]
+  [PluginFile("HeuristicLab.Algorithms.MemPR-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Analysis", "3.3")]
+  [PluginDependency("HeuristicLab.Collections", "3.3")]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Common.Resources", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Data", "3.3")]
+  [PluginDependency("HeuristicLab.Encodings.BinaryVectorEncoding", "3.3")]
+  [PluginDependency("HeuristicLab.Operators", "3.3")]
+  [PluginDependency("HeuristicLab.Optimization", "3.3")]
+  [PluginDependency("HeuristicLab.Parameters", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  [PluginDependency("HeuristicLab.Random", "3.3")]
+  public class HeuristicLabAlgorithmsMemPRPlugin : PluginBase {
+  }
+}
+
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Properties/AssemblyInfo.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Properties/AssemblyInfo.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Properties/AssemblyInfo.cs	(revision 14420)
@@ -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.Algorithms.MemPR")]
+[assembly: AssemblyDescription("Plugin that provides the MemPR (memetic path relinking) algorithm.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2016 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("9d274421-6332-4fbc-aae4-467ace27c368")]
+
+// 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.0")]
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/SingleObjectiveSolutionScope.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/SingleObjectiveSolutionScope.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/SingleObjectiveSolutionScope.cs	(revision 14420)
@@ -0,0 +1,147 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System.Drawing;
+using HeuristicLab.Collections;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Algorithms.MemPR {
+  [Item("MemPRScope", "Scope for a MemPR individual.")]
+  [StorableClass]
+  public sealed class SingleObjectiveSolutionScope<T> : NamedItem, ISingleObjectiveSolutionScope<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
+
+    public void Adopt(ISingleObjectiveSolutionScope<T> orphan) {
+      Solution = orphan.Solution;
+      Fitness = orphan.Fitness;
+    }
+
+    public void Adopt(ISolutionScope<T> orphan) {
+      Solution = orphan.Solution;
+      Fitness = double.NaN;
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Util/CkMeans1D.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Util/CkMeans1D.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/Util/CkMeans1D.cs	(revision 14420)
@@ -0,0 +1,109 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HeuristicLab.Common;
+
+namespace HeuristicLab.Algorithms.MemPR.Util {
+  /// <summary>
+  /// Implements the Ckmeans.1d.dp method. It is described in the paper:
+  /// Haizhou Wang and Mingzhou Song. 2011.
+  /// Ckmeans.1d.dp: Optimal k-means Clustering in One Dimension by Dynamic Programming
+  /// The R Journal Vol. 3/2, pp. 29-33.
+  /// available at https://journal.r-project.org/archive/2011-2/RJournal_2011-2_Wang+Song.pdf
+  /// </summary>
+  public class CkMeans1D {
+    /// <summary>
+    /// Clusters the 1-dimensional data given in <paramref name="estimations"/>.
+    /// </summary>
+    /// <param name="estimations">The 1-dimensional data that should be clustered.</param>
+    /// <param name="k">The maximum number of clusters.</param>
+    /// <param name="clusterValues">A vector of the same length as estimations that assigns to each point a cluster id.</param>
+    /// <returns>A sorted list of cluster centroids and corresponding cluster ids.</returns>
+    public static SortedList<double, int> Cluster(double[] estimations, int k, out int[] clusterValues) {
+      int nPoints = estimations.Length;
+      var distinct = estimations.Distinct().OrderBy(x => x).ToArray();
+      var max = distinct.Max();
+      if (distinct.Length <= k) {
+        var dict = distinct.Select((v, i) => new { Index = i, Value = v }).ToDictionary(x => x.Value, y => y.Index);
+        for (int i = distinct.Length; i < k; i++)
+          dict.Add(max + i - distinct.Length + 1, i);
+
+        clusterValues = new int[nPoints];
+        for (int i = 0; i < nPoints; i++)
+          if (!dict.ContainsKey(estimations[i])) clusterValues[i] = 0;
+          else clusterValues[i] = dict[estimations[i]];
+
+        return new SortedList<double, int>(dict);
+      }
+
+      var n = distinct.Length;
+      var D = new double[n, k];
+      var B = new int[n, k];
+
+      for (int m = 0; m < k; m++) {
+        for (int j = m; j <= n - k + m; j++) {
+          if (m == 0)
+            D[j, m] = SumOfSquaredDistances(distinct, 0, j + 1);
+          else {
+            var minD = double.MaxValue;
+            var minI = 0;
+            for (int i = 1; i <= j; i++) {
+              var d = D[i - 1, m - 1] + SumOfSquaredDistances(distinct, i, j + 1);
+              if (d < minD) {
+                minD = d;
+                minI = i;
+              }
+            }
+            D[j, m] = minD;
+            B[j, m] = minI;
+          }
+        }
+      }
+
+      var centers = new SortedList<double, int>();
+      var upper = B[n - 1, k - 1];
+      var c = Mean(distinct, upper, n);
+      centers.Add(c, k - 1);
+      for (int i = k - 2; i >= 0; i--) {
+        var lower = B[upper - 1, i];
+        var c2 = Mean(distinct, lower, upper);
+        centers.Add(c2, i);
+        upper = lower;
+      }
+
+      clusterValues = new int[nPoints];
+      for (int i = 0; i < estimations.Length; i++) {
+        clusterValues[i] = centers.MinItems(x => Math.Abs(estimations[i] - x.Key)).First().Value;
+      }
+
+      return centers;
+    }
+
+    private static double SumOfSquaredDistances(double[] x, int start, int end) {
+      if (start == end) throw new InvalidOperationException();
+      if (start + 1 == end) return 0.0;
+      double mean = 0.0;
+      for (int i = start; i < end; i++) {
+        mean += x[i];
+      }
+      mean /= (end - start);
+      var sum = 0.0;
+      for (int i = start; i < end; i++) {
+        sum += (x[i] - mean) * (x[i] - mean);
+      }
+      return sum;
+    }
+
+    private static double Mean(double[] x, int start, int end) {
+      if (start == end) throw new InvalidOperationException();
+      double mean = 0.0;
+      for (int i = start; i < end; i++) {
+        mean += x[i];
+      }
+      mean /= (end - start);
+      return mean;
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/ExecutionContext.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/ExecutionContext.cs	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/ExecutionContext.cs	(revision 14420)
@@ -77,12 +77,12 @@
       return new ExecutionContext(parent, op, scope);
     }
-    public IAtomicOperation CreateOperation(IOperator op, IScope scope) {
-      return new ExecutionContext(parent, op, scope);
+    public IAtomicOperation CreateOperation(IOperator op, IScope s) {
+      return new ExecutionContext(parent, op, s);
     }
     public IAtomicOperation CreateChildOperation(IOperator op) {
       return new ExecutionContext(this, op, scope);
     }
-    public IAtomicOperation CreateChildOperation(IOperator op, IScope scope) {
-      return new ExecutionContext(this, op, scope);
+    public IAtomicOperation CreateChildOperation(IOperator op, IScope s) {
+      return new ExecutionContext(this, op, s);
     }
   }
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/Interfaces/IExecutionContext.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/Interfaces/IExecutionContext.cs	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Core/3.3/Interfaces/IExecutionContext.cs	(revision 14420)
@@ -32,7 +32,7 @@
 
     IAtomicOperation CreateOperation(IOperator op);
-    IAtomicOperation CreateOperation(IOperator op, IScope scope);
+    IAtomicOperation CreateOperation(IOperator op, IScope s);
     IAtomicOperation CreateChildOperation(IOperator op);
-    IAtomicOperation CreateChildOperation(IOperator op, IScope scope);
+    IAtomicOperation CreateChildOperation(IOperator op, IScope s);
   }
 }
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/HeuristicLab.Optimization.Views-3.3.csproj	(revision 14420)
@@ -459,4 +459,7 @@
       <DependentUpon>CreateNewSingleEncodingDialog.cs</DependentUpon>
     </EmbeddedResource>
+    <EmbeddedResource Include="RunCollectionViews\RunCollectionRLDView.resx">
+      <DependentUpon>RunCollectionRLDView.cs</DependentUpon>
+    </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.Designer.cs	(revision 14420)
@@ -44,400 +44,400 @@
     /// </summary>
     private void InitializeComponent() {
-      this.components = new System.ComponentModel.Container();
-      System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea1 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
-      System.Windows.Forms.DataVisualization.Charting.Legend legend1 = new System.Windows.Forms.DataVisualization.Charting.Legend();
-      this.dataTableComboBox = new System.Windows.Forms.ComboBox();
-      this.dataTableLabel = new System.Windows.Forms.Label();
-      this.groupLabel = new System.Windows.Forms.Label();
-      this.groupComboBox = new System.Windows.Forms.ComboBox();
-      this.targetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
-      this.targetsTextBox = new System.Windows.Forms.TextBox();
-      this.targetsLabel = new System.Windows.Forms.Label();
-      this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
-      this.addTargetsAsResultButton = new System.Windows.Forms.Button();
-      this.generateTargetsButton = new System.Windows.Forms.Button();
-      this.toolTip = new System.Windows.Forms.ToolTip(this.components);
-      this.budgetsLabel = new System.Windows.Forms.Label();
-      this.budgetsTextBox = new System.Windows.Forms.TextBox();
-      this.addBudgetsAsResultButton = new System.Windows.Forms.Button();
-      this.aggregateTargetsCheckBox = new System.Windows.Forms.CheckBox();
-      this.tabControl = new System.Windows.Forms.TabControl();
-      this.byTargetTabPage = new System.Windows.Forms.TabPage();
-      this.targetChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
-      this.boundShadingCheckBox = new System.Windows.Forms.CheckBox();
-      this.byCostTabPage = new System.Windows.Forms.TabPage();
-      this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
-      this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
-      this.eachOrAllBudgetsCheckBox = new System.Windows.Forms.CheckBox();
-      this.generateBudgetsButton = new System.Windows.Forms.Button();
-      this.byTableTabPage = new System.Windows.Forms.TabPage();
-      this.ertTableView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
-      this.problemComboBox = new System.Windows.Forms.ComboBox();
-      this.problemLabel = new System.Windows.Forms.Label();
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
-      this.tabControl.SuspendLayout();
-      this.byTargetTabPage.SuspendLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).BeginInit();
-      this.byCostTabPage.SuspendLayout();
-      this.byTableTabPage.SuspendLayout();
-      this.SuspendLayout();
-      // 
-      // dataTableComboBox
-      // 
-      this.dataTableComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.dataTableComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-      this.dataTableComboBox.FormattingEnabled = true;
-      this.dataTableComboBox.Location = new System.Drawing.Point(69, 57);
-      this.dataTableComboBox.Name = "dataTableComboBox";
-      this.dataTableComboBox.Size = new System.Drawing.Size(582, 21);
-      this.dataTableComboBox.TabIndex = 5;
-      this.dataTableComboBox.SelectedIndexChanged += new System.EventHandler(this.dataTableComboBox_SelectedIndexChanged);
-      // 
-      // dataTableLabel
-      // 
-      this.dataTableLabel.AutoSize = true;
-      this.dataTableLabel.Location = new System.Drawing.Point(3, 60);
-      this.dataTableLabel.Name = "dataTableLabel";
-      this.dataTableLabel.Size = new System.Drawing.Size(60, 13);
-      this.dataTableLabel.TabIndex = 4;
-      this.dataTableLabel.Text = "DataTable:";
-      // 
-      // groupLabel
-      // 
-      this.groupLabel.AutoSize = true;
-      this.groupLabel.Location = new System.Drawing.Point(3, 6);
-      this.groupLabel.Name = "groupLabel";
-      this.groupLabel.Size = new System.Drawing.Size(39, 13);
-      this.groupLabel.TabIndex = 0;
-      this.groupLabel.Text = "Group:";
-      // 
-      // groupComboBox
-      // 
-      this.groupComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.groupComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-      this.groupComboBox.FormattingEnabled = true;
-      this.groupComboBox.Location = new System.Drawing.Point(69, 3);
-      this.groupComboBox.Name = "groupComboBox";
-      this.groupComboBox.Size = new System.Drawing.Size(582, 21);
-      this.groupComboBox.TabIndex = 1;
-      this.groupComboBox.SelectedIndexChanged += new System.EventHandler(this.groupComboBox_SelectedIndexChanged);
-      // 
-      // targetLogScalingCheckBox
-      // 
-      this.targetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.targetLogScalingCheckBox.AutoSize = true;
-      this.targetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
-      this.targetLogScalingCheckBox.Name = "targetLogScalingCheckBox";
-      this.targetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
-      this.targetLogScalingCheckBox.TabIndex = 6;
-      this.targetLogScalingCheckBox.Text = "logarithmic scaling";
-      this.targetLogScalingCheckBox.UseVisualStyleBackColor = true;
-      this.targetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
-      // 
-      // targetsTextBox
-      // 
-      this.targetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.targetsTextBox.Location = new System.Drawing.Point(59, 8);
-      this.targetsTextBox.Name = "targetsTextBox";
-      this.targetsTextBox.Size = new System.Drawing.Size(287, 20);
-      this.targetsTextBox.TabIndex = 1;
-      this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" +
+            this.components = new System.ComponentModel.Container();
+            System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea2 = new System.Windows.Forms.DataVisualization.Charting.ChartArea();
+            System.Windows.Forms.DataVisualization.Charting.Legend legend2 = new System.Windows.Forms.DataVisualization.Charting.Legend();
+            this.dataTableComboBox = new System.Windows.Forms.ComboBox();
+            this.dataTableLabel = new System.Windows.Forms.Label();
+            this.groupLabel = new System.Windows.Forms.Label();
+            this.groupComboBox = new System.Windows.Forms.ComboBox();
+            this.targetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
+            this.targetsTextBox = new System.Windows.Forms.TextBox();
+            this.targetsLabel = new System.Windows.Forms.Label();
+            this.errorProvider = new System.Windows.Forms.ErrorProvider(this.components);
+            this.addTargetsAsResultButton = new System.Windows.Forms.Button();
+            this.generateTargetsButton = new System.Windows.Forms.Button();
+            this.toolTip = new System.Windows.Forms.ToolTip(this.components);
+            this.budgetsLabel = new System.Windows.Forms.Label();
+            this.budgetsTextBox = new System.Windows.Forms.TextBox();
+            this.addBudgetsAsResultButton = new System.Windows.Forms.Button();
+            this.aggregateTargetsCheckBox = new System.Windows.Forms.CheckBox();
+            this.tabControl = new System.Windows.Forms.TabControl();
+            this.byTargetTabPage = new System.Windows.Forms.TabPage();
+            this.targetChart = new HeuristicLab.Visualization.ChartControlsExtensions.EnhancedChart();
+            this.boundShadingCheckBox = new System.Windows.Forms.CheckBox();
+            this.byCostTabPage = new System.Windows.Forms.TabPage();
+            this.byCostViewHost = new HeuristicLab.MainForm.WindowsForms.ViewHost();
+            this.budgetLogScalingCheckBox = new System.Windows.Forms.CheckBox();
+            this.eachOrAllBudgetsCheckBox = new System.Windows.Forms.CheckBox();
+            this.generateBudgetsButton = new System.Windows.Forms.Button();
+            this.byTableTabPage = new System.Windows.Forms.TabPage();
+            this.ertTableView = new HeuristicLab.Data.Views.StringConvertibleMatrixView();
+            this.problemComboBox = new System.Windows.Forms.ComboBox();
+            this.problemLabel = new System.Windows.Forms.Label();
+            ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
+            this.tabControl.SuspendLayout();
+            this.byTargetTabPage.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.targetChart)).BeginInit();
+            this.byCostTabPage.SuspendLayout();
+            this.byTableTabPage.SuspendLayout();
+            this.SuspendLayout();
+            // 
+            // dataTableComboBox
+            // 
+            this.dataTableComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.dataTableComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.dataTableComboBox.FormattingEnabled = true;
+            this.dataTableComboBox.Location = new System.Drawing.Point(69, 57);
+            this.dataTableComboBox.Name = "dataTableComboBox";
+            this.dataTableComboBox.Size = new System.Drawing.Size(582, 21);
+            this.dataTableComboBox.TabIndex = 5;
+            this.dataTableComboBox.SelectedIndexChanged += new System.EventHandler(this.dataTableComboBox_SelectedIndexChanged);
+            // 
+            // dataTableLabel
+            // 
+            this.dataTableLabel.AutoSize = true;
+            this.dataTableLabel.Location = new System.Drawing.Point(3, 60);
+            this.dataTableLabel.Name = "dataTableLabel";
+            this.dataTableLabel.Size = new System.Drawing.Size(60, 13);
+            this.dataTableLabel.TabIndex = 4;
+            this.dataTableLabel.Text = "DataTable:";
+            // 
+            // groupLabel
+            // 
+            this.groupLabel.AutoSize = true;
+            this.groupLabel.Location = new System.Drawing.Point(3, 6);
+            this.groupLabel.Name = "groupLabel";
+            this.groupLabel.Size = new System.Drawing.Size(39, 13);
+            this.groupLabel.TabIndex = 0;
+            this.groupLabel.Text = "Group:";
+            // 
+            // groupComboBox
+            // 
+            this.groupComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.groupComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.groupComboBox.FormattingEnabled = true;
+            this.groupComboBox.Location = new System.Drawing.Point(69, 3);
+            this.groupComboBox.Name = "groupComboBox";
+            this.groupComboBox.Size = new System.Drawing.Size(582, 21);
+            this.groupComboBox.TabIndex = 1;
+            this.groupComboBox.SelectedIndexChanged += new System.EventHandler(this.groupComboBox_SelectedIndexChanged);
+            // 
+            // targetLogScalingCheckBox
+            // 
+            this.targetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.targetLogScalingCheckBox.AutoSize = true;
+            this.targetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
+            this.targetLogScalingCheckBox.Name = "targetLogScalingCheckBox";
+            this.targetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+            this.targetLogScalingCheckBox.TabIndex = 6;
+            this.targetLogScalingCheckBox.Text = "logarithmic scaling";
+            this.targetLogScalingCheckBox.UseVisualStyleBackColor = true;
+            this.targetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+            // 
+            // targetsTextBox
+            // 
+            this.targetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.targetsTextBox.Location = new System.Drawing.Point(59, 8);
+            this.targetsTextBox.Name = "targetsTextBox";
+            this.targetsTextBox.Size = new System.Drawing.Size(287, 20);
+            this.targetsTextBox.TabIndex = 1;
+            this.toolTip.SetToolTip(this.targetsTextBox, "The order of the targets is important, first to-hit targets\r\nshould be given firs" +
         "t. The sequence should be monotonous.\r\n\r\nTargets should be separated by semicolo" +
         "n, tab or space.");
-      this.targetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.targetsTextBox_Validating);
-      // 
-      // targetsLabel
-      // 
-      this.targetsLabel.AutoSize = true;
-      this.targetsLabel.Location = new System.Drawing.Point(6, 11);
-      this.targetsLabel.Name = "targetsLabel";
-      this.targetsLabel.Size = new System.Drawing.Size(46, 13);
-      this.targetsLabel.TabIndex = 0;
-      this.targetsLabel.Text = "Targets:";
-      // 
-      // errorProvider
-      // 
-      this.errorProvider.ContainerControl = this;
-      // 
-      // addTargetsAsResultButton
-      // 
-      this.addTargetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.addTargetsAsResultButton.Location = new System.Drawing.Point(551, 6);
-      this.addTargetsAsResultButton.Name = "addTargetsAsResultButton";
-      this.addTargetsAsResultButton.Size = new System.Drawing.Size(89, 23);
-      this.addTargetsAsResultButton.TabIndex = 4;
-      this.addTargetsAsResultButton.Text = "Add as Result";
-      this.addTargetsAsResultButton.UseVisualStyleBackColor = true;
-      this.addTargetsAsResultButton.Click += new System.EventHandler(this.addTargetsAsResultButton_Click);
-      // 
-      // generateTargetsButton
-      // 
-      this.generateTargetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.generateTargetsButton.Location = new System.Drawing.Point(456, 6);
-      this.generateTargetsButton.Name = "generateTargetsButton";
-      this.generateTargetsButton.Size = new System.Drawing.Size(89, 23);
-      this.generateTargetsButton.TabIndex = 3;
-      this.generateTargetsButton.Text = "Generate...";
-      this.generateTargetsButton.UseVisualStyleBackColor = true;
-      this.generateTargetsButton.Click += new System.EventHandler(this.generateTargetsButton_Click);
-      // 
-      // budgetsLabel
-      // 
-      this.budgetsLabel.AutoSize = true;
-      this.budgetsLabel.Location = new System.Drawing.Point(6, 11);
-      this.budgetsLabel.Name = "budgetsLabel";
-      this.budgetsLabel.Size = new System.Drawing.Size(49, 13);
-      this.budgetsLabel.TabIndex = 1;
-      this.budgetsLabel.Text = "Budgets:";
-      // 
-      // budgetsTextBox
-      // 
-      this.budgetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.budgetsTextBox.Location = new System.Drawing.Point(59, 8);
-      this.budgetsTextBox.Name = "budgetsTextBox";
-      this.budgetsTextBox.Size = new System.Drawing.Size(326, 20);
-      this.budgetsTextBox.TabIndex = 6;
-      this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.budgetsTextBox_Validating);
-      // 
-      // addBudgetsAsResultButton
-      // 
-      this.addBudgetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.addBudgetsAsResultButton.Location = new System.Drawing.Point(551, 6);
-      this.addBudgetsAsResultButton.Name = "addBudgetsAsResultButton";
-      this.addBudgetsAsResultButton.Size = new System.Drawing.Size(89, 23);
-      this.addBudgetsAsResultButton.TabIndex = 7;
-      this.addBudgetsAsResultButton.Text = "Add as Result";
-      this.addBudgetsAsResultButton.UseVisualStyleBackColor = true;
-      this.addBudgetsAsResultButton.Click += new System.EventHandler(this.addBudgetsAsResultButton_Click);
-      // 
-      // aggregateTargetsCheckBox
-      // 
-      this.aggregateTargetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.aggregateTargetsCheckBox.AutoSize = true;
-      this.aggregateTargetsCheckBox.Checked = true;
-      this.aggregateTargetsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(352, 10);
-      this.aggregateTargetsCheckBox.Name = "aggregateTargetsCheckBox";
-      this.aggregateTargetsCheckBox.Size = new System.Drawing.Size(74, 17);
-      this.aggregateTargetsCheckBox.TabIndex = 2;
-      this.aggregateTargetsCheckBox.Text = "aggregate";
-      this.aggregateTargetsCheckBox.UseVisualStyleBackColor = true;
-      this.aggregateTargetsCheckBox.CheckedChanged += new System.EventHandler(this.aggregateTargetsCheckBox_CheckedChanged);
-      // 
-      // tabControl
-      // 
-      this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            this.targetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.targetsTextBox_Validating);
+            // 
+            // targetsLabel
+            // 
+            this.targetsLabel.AutoSize = true;
+            this.targetsLabel.Location = new System.Drawing.Point(6, 11);
+            this.targetsLabel.Name = "targetsLabel";
+            this.targetsLabel.Size = new System.Drawing.Size(46, 13);
+            this.targetsLabel.TabIndex = 0;
+            this.targetsLabel.Text = "Targets:";
+            // 
+            // errorProvider
+            // 
+            this.errorProvider.ContainerControl = this;
+            // 
+            // addTargetsAsResultButton
+            // 
+            this.addTargetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.addTargetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+            this.addTargetsAsResultButton.Name = "addTargetsAsResultButton";
+            this.addTargetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+            this.addTargetsAsResultButton.TabIndex = 4;
+            this.addTargetsAsResultButton.Text = "Add as Result";
+            this.addTargetsAsResultButton.UseVisualStyleBackColor = true;
+            this.addTargetsAsResultButton.Click += new System.EventHandler(this.addTargetsAsResultButton_Click);
+            // 
+            // generateTargetsButton
+            // 
+            this.generateTargetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.generateTargetsButton.Location = new System.Drawing.Point(456, 6);
+            this.generateTargetsButton.Name = "generateTargetsButton";
+            this.generateTargetsButton.Size = new System.Drawing.Size(89, 23);
+            this.generateTargetsButton.TabIndex = 3;
+            this.generateTargetsButton.Text = "Generate...";
+            this.generateTargetsButton.UseVisualStyleBackColor = true;
+            this.generateTargetsButton.Click += new System.EventHandler(this.generateTargetsButton_Click);
+            // 
+            // budgetsLabel
+            // 
+            this.budgetsLabel.AutoSize = true;
+            this.budgetsLabel.Location = new System.Drawing.Point(6, 11);
+            this.budgetsLabel.Name = "budgetsLabel";
+            this.budgetsLabel.Size = new System.Drawing.Size(49, 13);
+            this.budgetsLabel.TabIndex = 1;
+            this.budgetsLabel.Text = "Budgets:";
+            // 
+            // budgetsTextBox
+            // 
+            this.budgetsTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.budgetsTextBox.Location = new System.Drawing.Point(59, 8);
+            this.budgetsTextBox.Name = "budgetsTextBox";
+            this.budgetsTextBox.Size = new System.Drawing.Size(326, 20);
+            this.budgetsTextBox.TabIndex = 6;
+            this.budgetsTextBox.Validating += new System.ComponentModel.CancelEventHandler(this.budgetsTextBox_Validating);
+            // 
+            // addBudgetsAsResultButton
+            // 
+            this.addBudgetsAsResultButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.addBudgetsAsResultButton.Location = new System.Drawing.Point(551, 6);
+            this.addBudgetsAsResultButton.Name = "addBudgetsAsResultButton";
+            this.addBudgetsAsResultButton.Size = new System.Drawing.Size(89, 23);
+            this.addBudgetsAsResultButton.TabIndex = 7;
+            this.addBudgetsAsResultButton.Text = "Add as Result";
+            this.addBudgetsAsResultButton.UseVisualStyleBackColor = true;
+            this.addBudgetsAsResultButton.Click += new System.EventHandler(this.addBudgetsAsResultButton_Click);
+            // 
+            // aggregateTargetsCheckBox
+            // 
+            this.aggregateTargetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.aggregateTargetsCheckBox.AutoSize = true;
+            this.aggregateTargetsCheckBox.Checked = true;
+            this.aggregateTargetsCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.aggregateTargetsCheckBox.Location = new System.Drawing.Point(352, 10);
+            this.aggregateTargetsCheckBox.Name = "aggregateTargetsCheckBox";
+            this.aggregateTargetsCheckBox.Size = new System.Drawing.Size(74, 17);
+            this.aggregateTargetsCheckBox.TabIndex = 2;
+            this.aggregateTargetsCheckBox.Text = "aggregate";
+            this.aggregateTargetsCheckBox.UseVisualStyleBackColor = true;
+            this.aggregateTargetsCheckBox.CheckedChanged += new System.EventHandler(this.aggregateTargetsCheckBox_CheckedChanged);
+            // 
+            // tabControl
+            // 
+            this.tabControl.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      this.tabControl.Controls.Add(this.byTargetTabPage);
-      this.tabControl.Controls.Add(this.byCostTabPage);
-      this.tabControl.Controls.Add(this.byTableTabPage);
-      this.tabControl.Location = new System.Drawing.Point(0, 84);
-      this.tabControl.Name = "tabControl";
-      this.tabControl.SelectedIndex = 0;
-      this.tabControl.Size = new System.Drawing.Size(654, 413);
-      this.tabControl.TabIndex = 6;
-      // 
-      // byTargetTabPage
-      // 
-      this.byTargetTabPage.Controls.Add(this.targetChart);
-      this.byTargetTabPage.Controls.Add(this.boundShadingCheckBox);
-      this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox);
-      this.byTargetTabPage.Controls.Add(this.targetsLabel);
-      this.byTargetTabPage.Controls.Add(this.aggregateTargetsCheckBox);
-      this.byTargetTabPage.Controls.Add(this.targetsTextBox);
-      this.byTargetTabPage.Controls.Add(this.generateTargetsButton);
-      this.byTargetTabPage.Controls.Add(this.addTargetsAsResultButton);
-      this.byTargetTabPage.Location = new System.Drawing.Point(4, 22);
-      this.byTargetTabPage.Name = "byTargetTabPage";
-      this.byTargetTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.byTargetTabPage.Size = new System.Drawing.Size(646, 387);
-      this.byTargetTabPage.TabIndex = 0;
-      this.byTargetTabPage.Text = "Performance by Target";
-      this.byTargetTabPage.UseVisualStyleBackColor = true;
-      // 
-      // targetChart
-      // 
-      this.targetChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            this.tabControl.Controls.Add(this.byTargetTabPage);
+            this.tabControl.Controls.Add(this.byCostTabPage);
+            this.tabControl.Controls.Add(this.byTableTabPage);
+            this.tabControl.Location = new System.Drawing.Point(0, 84);
+            this.tabControl.Name = "tabControl";
+            this.tabControl.SelectedIndex = 0;
+            this.tabControl.Size = new System.Drawing.Size(654, 413);
+            this.tabControl.TabIndex = 6;
+            // 
+            // byTargetTabPage
+            // 
+            this.byTargetTabPage.Controls.Add(this.targetChart);
+            this.byTargetTabPage.Controls.Add(this.boundShadingCheckBox);
+            this.byTargetTabPage.Controls.Add(this.targetLogScalingCheckBox);
+            this.byTargetTabPage.Controls.Add(this.targetsLabel);
+            this.byTargetTabPage.Controls.Add(this.aggregateTargetsCheckBox);
+            this.byTargetTabPage.Controls.Add(this.targetsTextBox);
+            this.byTargetTabPage.Controls.Add(this.generateTargetsButton);
+            this.byTargetTabPage.Controls.Add(this.addTargetsAsResultButton);
+            this.byTargetTabPage.Location = new System.Drawing.Point(4, 22);
+            this.byTargetTabPage.Name = "byTargetTabPage";
+            this.byTargetTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.byTargetTabPage.Size = new System.Drawing.Size(646, 387);
+            this.byTargetTabPage.TabIndex = 0;
+            this.byTargetTabPage.Text = "Performance by Target";
+            this.byTargetTabPage.UseVisualStyleBackColor = true;
+            // 
+            // targetChart
+            // 
+            this.targetChart.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      chartArea1.AxisX.IsStartedFromZero = false;
-      chartArea1.AxisX.MinorGrid.Enabled = true;
-      chartArea1.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
-      chartArea1.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
-      chartArea1.AxisY.Maximum = 1D;
-      chartArea1.AxisY.Minimum = 0D;
-      chartArea1.AxisY.MinorGrid.Enabled = true;
-      chartArea1.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
-      chartArea1.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
-      chartArea1.Name = "ChartArea1";
-      this.targetChart.ChartAreas.Add(chartArea1);
-      legend1.Alignment = System.Drawing.StringAlignment.Center;
-      legend1.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
-      legend1.Name = "Legend1";
-      this.targetChart.Legends.Add(legend1);
-      this.targetChart.Location = new System.Drawing.Point(6, 34);
-      this.targetChart.Name = "targetChart";
-      this.targetChart.Size = new System.Drawing.Size(634, 324);
-      this.targetChart.SuppressExceptions = true;
-      this.targetChart.TabIndex = 7;
-      this.targetChart.Text = "enhancedChart1";
-      this.targetChart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
-      this.targetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
-      this.targetChart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
-      // 
-      // boundShadingCheckBox
-      // 
-      this.boundShadingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.boundShadingCheckBox.AutoSize = true;
-      this.boundShadingCheckBox.Checked = true;
-      this.boundShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
-      this.boundShadingCheckBox.Location = new System.Drawing.Point(127, 364);
-      this.boundShadingCheckBox.Name = "boundShadingCheckBox";
-      this.boundShadingCheckBox.Size = new System.Drawing.Size(96, 17);
-      this.boundShadingCheckBox.TabIndex = 6;
-      this.boundShadingCheckBox.Text = "bound shading";
-      this.boundShadingCheckBox.UseVisualStyleBackColor = true;
-      this.boundShadingCheckBox.CheckedChanged += new System.EventHandler(this.boundShadingCheckBox_CheckedChanged);
-      // 
-      // byCostTabPage
-      // 
-      this.byCostTabPage.Controls.Add(this.byCostViewHost);
-      this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox);
-      this.byCostTabPage.Controls.Add(this.eachOrAllBudgetsCheckBox);
-      this.byCostTabPage.Controls.Add(this.generateBudgetsButton);
-      this.byCostTabPage.Controls.Add(this.budgetsLabel);
-      this.byCostTabPage.Controls.Add(this.addBudgetsAsResultButton);
-      this.byCostTabPage.Controls.Add(this.budgetsTextBox);
-      this.byCostTabPage.Location = new System.Drawing.Point(4, 22);
-      this.byCostTabPage.Name = "byCostTabPage";
-      this.byCostTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.byCostTabPage.Size = new System.Drawing.Size(646, 387);
-      this.byCostTabPage.TabIndex = 1;
-      this.byCostTabPage.Text = "Performance by Cost";
-      this.byCostTabPage.UseVisualStyleBackColor = true;
-      // 
-      // byCostViewHost
-      // 
-      this.byCostViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            chartArea2.AxisX.IsStartedFromZero = false;
+            chartArea2.AxisX.MinorGrid.Enabled = true;
+            chartArea2.AxisX.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+            chartArea2.AxisX.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+            chartArea2.AxisY.Maximum = 1D;
+            chartArea2.AxisY.Minimum = 0D;
+            chartArea2.AxisY.MinorGrid.Enabled = true;
+            chartArea2.AxisY.MinorGrid.LineColor = System.Drawing.Color.WhiteSmoke;
+            chartArea2.AxisY.MinorGrid.LineDashStyle = System.Windows.Forms.DataVisualization.Charting.ChartDashStyle.Dash;
+            chartArea2.Name = "ChartArea1";
+            this.targetChart.ChartAreas.Add(chartArea2);
+            legend2.Alignment = System.Drawing.StringAlignment.Center;
+            legend2.Docking = System.Windows.Forms.DataVisualization.Charting.Docking.Top;
+            legend2.Name = "Legend1";
+            this.targetChart.Legends.Add(legend2);
+            this.targetChart.Location = new System.Drawing.Point(6, 34);
+            this.targetChart.Name = "targetChart";
+            this.targetChart.Size = new System.Drawing.Size(634, 324);
+            this.targetChart.SuppressExceptions = true;
+            this.targetChart.TabIndex = 7;
+            this.targetChart.Text = "enhancedChart1";
+            this.targetChart.CustomizeLegend += new System.EventHandler<System.Windows.Forms.DataVisualization.Charting.CustomizeLegendEventArgs>(this.chart_CustomizeLegend);
+            this.targetChart.MouseDown += new System.Windows.Forms.MouseEventHandler(this.chart_MouseDown);
+            this.targetChart.MouseMove += new System.Windows.Forms.MouseEventHandler(this.chart_MouseMove);
+            // 
+            // boundShadingCheckBox
+            // 
+            this.boundShadingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.boundShadingCheckBox.AutoSize = true;
+            this.boundShadingCheckBox.Checked = true;
+            this.boundShadingCheckBox.CheckState = System.Windows.Forms.CheckState.Checked;
+            this.boundShadingCheckBox.Location = new System.Drawing.Point(127, 364);
+            this.boundShadingCheckBox.Name = "boundShadingCheckBox";
+            this.boundShadingCheckBox.Size = new System.Drawing.Size(96, 17);
+            this.boundShadingCheckBox.TabIndex = 6;
+            this.boundShadingCheckBox.Text = "bound shading";
+            this.boundShadingCheckBox.UseVisualStyleBackColor = true;
+            this.boundShadingCheckBox.CheckedChanged += new System.EventHandler(this.boundShadingCheckBox_CheckedChanged);
+            // 
+            // byCostTabPage
+            // 
+            this.byCostTabPage.Controls.Add(this.byCostViewHost);
+            this.byCostTabPage.Controls.Add(this.budgetLogScalingCheckBox);
+            this.byCostTabPage.Controls.Add(this.eachOrAllBudgetsCheckBox);
+            this.byCostTabPage.Controls.Add(this.generateBudgetsButton);
+            this.byCostTabPage.Controls.Add(this.budgetsLabel);
+            this.byCostTabPage.Controls.Add(this.addBudgetsAsResultButton);
+            this.byCostTabPage.Controls.Add(this.budgetsTextBox);
+            this.byCostTabPage.Location = new System.Drawing.Point(4, 22);
+            this.byCostTabPage.Name = "byCostTabPage";
+            this.byCostTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.byCostTabPage.Size = new System.Drawing.Size(646, 387);
+            this.byCostTabPage.TabIndex = 1;
+            this.byCostTabPage.Text = "Performance by Cost";
+            this.byCostTabPage.UseVisualStyleBackColor = true;
+            // 
+            // byCostViewHost
+            // 
+            this.byCostViewHost.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-      this.byCostViewHost.Caption = "View";
-      this.byCostViewHost.Content = null;
-      this.byCostViewHost.Enabled = false;
-      this.byCostViewHost.Location = new System.Drawing.Point(6, 34);
-      this.byCostViewHost.Name = "byCostViewHost";
-      this.byCostViewHost.ReadOnly = false;
-      this.byCostViewHost.Size = new System.Drawing.Size(634, 324);
-      this.byCostViewHost.TabIndex = 12;
-      this.byCostViewHost.ViewsLabelVisible = true;
-      this.byCostViewHost.ViewType = null;
-      // 
-      // budgetLogScalingCheckBox
-      // 
-      this.budgetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-      this.budgetLogScalingCheckBox.AutoSize = true;
-      this.budgetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
-      this.budgetLogScalingCheckBox.Name = "budgetLogScalingCheckBox";
-      this.budgetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
-      this.budgetLogScalingCheckBox.TabIndex = 11;
-      this.budgetLogScalingCheckBox.Text = "logarithmic scaling";
-      this.budgetLogScalingCheckBox.UseVisualStyleBackColor = true;
-      this.budgetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
-      // 
-      // eachOrAllBudgetsCheckBox
-      // 
-      this.eachOrAllBudgetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.eachOrAllBudgetsCheckBox.AutoSize = true;
-      this.eachOrAllBudgetsCheckBox.Location = new System.Drawing.Point(414, 10);
-      this.eachOrAllBudgetsCheckBox.Name = "eachOrAllBudgetsCheckBox";
-      this.eachOrAllBudgetsCheckBox.Size = new System.Drawing.Size(36, 17);
-      this.eachOrAllBudgetsCheckBox.TabIndex = 10;
-      this.eachOrAllBudgetsCheckBox.Text = "all";
-      this.eachOrAllBudgetsCheckBox.UseVisualStyleBackColor = true;
-      this.eachOrAllBudgetsCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllBudgetsCheckBox_CheckedChanged);
-      // 
-      // generateBudgetsButton
-      // 
-      this.generateBudgetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
-      this.generateBudgetsButton.Location = new System.Drawing.Point(456, 6);
-      this.generateBudgetsButton.Name = "generateBudgetsButton";
-      this.generateBudgetsButton.Size = new System.Drawing.Size(89, 23);
-      this.generateBudgetsButton.TabIndex = 9;
-      this.generateBudgetsButton.Text = "Generate...";
-      this.generateBudgetsButton.UseVisualStyleBackColor = true;
-      this.generateBudgetsButton.Click += new System.EventHandler(this.generateBudgetsButton_Click);
-      // 
-      // byTableTabPage
-      // 
-      this.byTableTabPage.Controls.Add(this.ertTableView);
-      this.byTableTabPage.Location = new System.Drawing.Point(4, 22);
-      this.byTableTabPage.Name = "byTableTabPage";
-      this.byTableTabPage.Padding = new System.Windows.Forms.Padding(3);
-      this.byTableTabPage.Size = new System.Drawing.Size(646, 387);
-      this.byTableTabPage.TabIndex = 2;
-      this.byTableTabPage.Text = "Expected Runtime Tables";
-      this.byTableTabPage.UseVisualStyleBackColor = true;
-      // 
-      // ertTableView
-      // 
-      this.ertTableView.Caption = "StringConvertibleMatrix View";
-      this.ertTableView.Content = null;
-      this.ertTableView.Dock = System.Windows.Forms.DockStyle.Fill;
-      this.ertTableView.Location = new System.Drawing.Point(3, 3);
-      this.ertTableView.Name = "ertTableView";
-      this.ertTableView.ReadOnly = false;
-      this.ertTableView.ShowRowsAndColumnsTextBox = false;
-      this.ertTableView.ShowStatisticalInformation = false;
-      this.ertTableView.Size = new System.Drawing.Size(640, 381);
-      this.ertTableView.TabIndex = 0;
-      // 
-      // problemComboBox
-      // 
-      this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
-      this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
-      this.problemComboBox.FormattingEnabled = true;
-      this.problemComboBox.Location = new System.Drawing.Point(69, 30);
-      this.problemComboBox.Name = "problemComboBox";
-      this.problemComboBox.Size = new System.Drawing.Size(582, 21);
-      this.problemComboBox.TabIndex = 3;
-      this.problemComboBox.SelectedIndexChanged += new System.EventHandler(this.problemComboBox_SelectedIndexChanged);
-      // 
-      // problemLabel
-      // 
-      this.problemLabel.AutoSize = true;
-      this.problemLabel.Location = new System.Drawing.Point(3, 33);
-      this.problemLabel.Name = "problemLabel";
-      this.problemLabel.Size = new System.Drawing.Size(48, 13);
-      this.problemLabel.TabIndex = 2;
-      this.problemLabel.Text = "Problem:";
-      // 
-      // RunCollectionRLDView
-      // 
-      this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
-      this.Controls.Add(this.tabControl);
-      this.Controls.Add(this.groupComboBox);
-      this.Controls.Add(this.groupLabel);
-      this.Controls.Add(this.problemLabel);
-      this.Controls.Add(this.dataTableLabel);
-      this.Controls.Add(this.problemComboBox);
-      this.Controls.Add(this.dataTableComboBox);
-      this.Name = "RunCollectionRLDView";
-      this.Size = new System.Drawing.Size(654, 497);
-      ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
-      this.tabControl.ResumeLayout(false);
-      this.byTargetTabPage.ResumeLayout(false);
-      this.byTargetTabPage.PerformLayout();
-      ((System.ComponentModel.ISupportInitialize)(this.targetChart)).EndInit();
-      this.byCostTabPage.ResumeLayout(false);
-      this.byCostTabPage.PerformLayout();
-      this.byTableTabPage.ResumeLayout(false);
-      this.ResumeLayout(false);
-      this.PerformLayout();
+            this.byCostViewHost.Caption = "View";
+            this.byCostViewHost.Content = null;
+            this.byCostViewHost.Enabled = false;
+            this.byCostViewHost.Location = new System.Drawing.Point(6, 34);
+            this.byCostViewHost.Name = "byCostViewHost";
+            this.byCostViewHost.ReadOnly = false;
+            this.byCostViewHost.Size = new System.Drawing.Size(634, 324);
+            this.byCostViewHost.TabIndex = 12;
+            this.byCostViewHost.ViewsLabelVisible = true;
+            this.byCostViewHost.ViewType = null;
+            // 
+            // budgetLogScalingCheckBox
+            // 
+            this.budgetLogScalingCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
+            this.budgetLogScalingCheckBox.AutoSize = true;
+            this.budgetLogScalingCheckBox.Location = new System.Drawing.Point(9, 364);
+            this.budgetLogScalingCheckBox.Name = "budgetLogScalingCheckBox";
+            this.budgetLogScalingCheckBox.Size = new System.Drawing.Size(112, 17);
+            this.budgetLogScalingCheckBox.TabIndex = 11;
+            this.budgetLogScalingCheckBox.Text = "logarithmic scaling";
+            this.budgetLogScalingCheckBox.UseVisualStyleBackColor = true;
+            this.budgetLogScalingCheckBox.CheckedChanged += new System.EventHandler(this.logScalingCheckBox_CheckedChanged);
+            // 
+            // eachOrAllBudgetsCheckBox
+            // 
+            this.eachOrAllBudgetsCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.eachOrAllBudgetsCheckBox.AutoSize = true;
+            this.eachOrAllBudgetsCheckBox.Location = new System.Drawing.Point(414, 10);
+            this.eachOrAllBudgetsCheckBox.Name = "eachOrAllBudgetsCheckBox";
+            this.eachOrAllBudgetsCheckBox.Size = new System.Drawing.Size(36, 17);
+            this.eachOrAllBudgetsCheckBox.TabIndex = 10;
+            this.eachOrAllBudgetsCheckBox.Text = "all";
+            this.eachOrAllBudgetsCheckBox.UseVisualStyleBackColor = true;
+            this.eachOrAllBudgetsCheckBox.CheckedChanged += new System.EventHandler(this.eachOrAllBudgetsCheckBox_CheckedChanged);
+            // 
+            // generateBudgetsButton
+            // 
+            this.generateBudgetsButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+            this.generateBudgetsButton.Location = new System.Drawing.Point(456, 6);
+            this.generateBudgetsButton.Name = "generateBudgetsButton";
+            this.generateBudgetsButton.Size = new System.Drawing.Size(89, 23);
+            this.generateBudgetsButton.TabIndex = 9;
+            this.generateBudgetsButton.Text = "Generate...";
+            this.generateBudgetsButton.UseVisualStyleBackColor = true;
+            this.generateBudgetsButton.Click += new System.EventHandler(this.generateBudgetsButton_Click);
+            // 
+            // byTableTabPage
+            // 
+            this.byTableTabPage.Controls.Add(this.ertTableView);
+            this.byTableTabPage.Location = new System.Drawing.Point(4, 22);
+            this.byTableTabPage.Name = "byTableTabPage";
+            this.byTableTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.byTableTabPage.Size = new System.Drawing.Size(646, 387);
+            this.byTableTabPage.TabIndex = 2;
+            this.byTableTabPage.Text = "Expected Runtime Tables";
+            this.byTableTabPage.UseVisualStyleBackColor = true;
+            // 
+            // ertTableView
+            // 
+            this.ertTableView.Caption = "StringConvertibleMatrix View";
+            this.ertTableView.Content = null;
+            this.ertTableView.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.ertTableView.Location = new System.Drawing.Point(3, 3);
+            this.ertTableView.Name = "ertTableView";
+            this.ertTableView.ReadOnly = false;
+            this.ertTableView.ShowRowsAndColumnsTextBox = false;
+            this.ertTableView.ShowStatisticalInformation = false;
+            this.ertTableView.Size = new System.Drawing.Size(640, 381);
+            this.ertTableView.TabIndex = 0;
+            // 
+            // problemComboBox
+            // 
+            this.problemComboBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
+            | System.Windows.Forms.AnchorStyles.Right)));
+            this.problemComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+            this.problemComboBox.FormattingEnabled = true;
+            this.problemComboBox.Location = new System.Drawing.Point(69, 30);
+            this.problemComboBox.Name = "problemComboBox";
+            this.problemComboBox.Size = new System.Drawing.Size(582, 21);
+            this.problemComboBox.TabIndex = 3;
+            this.problemComboBox.SelectedIndexChanged += new System.EventHandler(this.problemComboBox_SelectedIndexChanged);
+            // 
+            // problemLabel
+            // 
+            this.problemLabel.AutoSize = true;
+            this.problemLabel.Location = new System.Drawing.Point(3, 33);
+            this.problemLabel.Name = "problemLabel";
+            this.problemLabel.Size = new System.Drawing.Size(48, 13);
+            this.problemLabel.TabIndex = 2;
+            this.problemLabel.Text = "Problem:";
+            // 
+            // RunCollectionRLDView
+            // 
+            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
+            this.Controls.Add(this.tabControl);
+            this.Controls.Add(this.groupComboBox);
+            this.Controls.Add(this.groupLabel);
+            this.Controls.Add(this.problemLabel);
+            this.Controls.Add(this.dataTableLabel);
+            this.Controls.Add(this.problemComboBox);
+            this.Controls.Add(this.dataTableComboBox);
+            this.Name = "RunCollectionRLDView";
+            this.Size = new System.Drawing.Size(654, 497);
+            ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
+            this.tabControl.ResumeLayout(false);
+            this.byTargetTabPage.ResumeLayout(false);
+            this.byTargetTabPage.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.targetChart)).EndInit();
+            this.byCostTabPage.ResumeLayout(false);
+            this.byCostTabPage.PerformLayout();
+            this.byTableTabPage.ResumeLayout(false);
+            this.ResumeLayout(false);
+            this.PerformLayout();
 
     }
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.cs	(revision 14420)
@@ -407,5 +407,6 @@
             IsVisibleInLegend = false,
             ChartType = SeriesChartType.Range,
-            Color = Color.FromArgb(32, colors[colorCount])
+            Color = Color.FromArgb(32, colors[colorCount]),
+            YValuesPerPoint = 2
           };
 
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.resx
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.resx	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Optimization.Views/3.3/RunCollectionViews/RunCollectionRLDView.resx	(revision 14420)
@@ -0,0 +1,129 @@
+﻿<?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>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>140, 17</value>
+  </metadata>
+  <metadata name="errorProvider.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>17, 17</value>
+  </metadata>
+  <metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>140, 17</value>
+  </metadata>
+</root>
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/BinaryKnapsackProblem.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/BinaryKnapsackProblem.cs	(revision 14420)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/BinaryKnapsackProblem.cs	(revision 14420)
@@ -0,0 +1,121 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.BinaryVectorEncoding;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.Binary {
+  [Item("Binary Knapsack Problem (BKSP)", "Represents a problem whose objective is to maximize the number of true values.")]
+  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 999)]
+  [StorableClass]
+  public class BinaryKnapsackProblem : BinaryProblem {
+    public override bool Maximization {
+      get { return true; }
+    }
+
+    #region Parameter Properties
+    public ValueParameter<IntValue> KnapsackCapacityParameter {
+      get { return (ValueParameter<IntValue>)Parameters["KnapsackCapacity"]; }
+    }
+    public ValueParameter<IntArray> WeightsParameter {
+      get { return (ValueParameter<IntArray>)Parameters["Weights"]; }
+    }
+    public ValueParameter<IntArray> ValuesParameter {
+      get { return (ValueParameter<IntArray>)Parameters["Values"]; }
+    }
+    #endregion
+
+    #region Properties
+    public IntValue KnapsackCapacity {
+      get { return KnapsackCapacityParameter.Value; }
+      set { KnapsackCapacityParameter.Value = value; }
+    }
+    public IntArray Weights {
+      get { return WeightsParameter.Value; }
+      set { WeightsParameter.Value = value; }
+    }
+    public IntArray Values {
+      get { return ValuesParameter.Value; }
+      set { ValuesParameter.Value = value; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected BinaryKnapsackProblem(bool deserializing) : base(deserializing) { }
+    protected BinaryKnapsackProblem(BinaryKnapsackProblem original, Cloner cloner) : base(original, cloner) { }
+    public BinaryKnapsackProblem()
+      : base() {
+      Encoding.Length = 5;
+      Parameters.Add(new ValueParameter<IntValue>("KnapsackCapacity", "Capacity of the Knapsack.", new IntValue(0)));
+      Parameters.Add(new ValueParameter<IntArray>("Weights", "The weights of the items.", new IntArray(5)));
+      Parameters.Add(new ValueParameter<IntArray>("Values", "The values of the items.", new IntArray(5)));
+
+      InitializeRandomKnapsackInstance();
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new BinaryKnapsackProblem(this, cloner);
+    }
+
+    public override double Evaluate(BinaryVector vector, IRandom random) {
+      var itemWeights = Weights;
+      var itemValues = Values;
+      var weight = 0;
+      var value = 0;
+      for (var i = 0; i < vector.Length; i++) {
+        if (!vector[i]) continue;
+        weight += itemWeights[i];
+        value += itemValues[i];
+      }
+      var cap = KnapsackCapacity.Value;
+      // assuming only positive values in the knapsack, maximizing in negative
+      // range makes solutions feasible, in positive range increases their value
+      return weight <= cap ? value : cap - weight;
+    }
+
+    private void InitializeRandomKnapsackInstance() {
+      var rand = new System.Random();
+
+      var itemCount = (int)Math.Pow(2, rand.Next(5, 10));
+      Weights = new IntArray(itemCount);
+      Values = new IntArray(itemCount);
+
+      double totalWeight = 0;
+
+      for (var i = 0; i < itemCount; i++) {
+        var value = rand.Next(1, 50);
+        var weight = rand.Next(1, 50);
+
+        Values[i] = value;
+        Weights[i] = weight;
+        totalWeight += weight;
+      }
+      
+      KnapsackCapacity = new IntValue((int)Math.Round(0.6 * totalWeight));
+      Encoding.Length = itemCount;
+    }
+  }
+}
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/HeuristicLab.Problems.Binary-3.3.csproj
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/HeuristicLab.Problems.Binary-3.3.csproj	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Problems.Binary/3.3/HeuristicLab.Problems.Binary-3.3.csproj	(revision 14420)
@@ -86,4 +86,5 @@
     <Compile Include="DeceptiveTrapProblem.cs" />
     <Compile Include="HIFFProblem.cs" />
+    <Compile Include="BinaryKnapsackProblem.cs" />
     <Compile Include="OneMaxProblem.cs" />
     <Compile Include="Plugin.cs" />
Index: branches/ScopedBasicAlgorithm/HeuristicLab.Random/3.3/RandomEnumerable.cs
===================================================================
--- branches/ScopedBasicAlgorithm/HeuristicLab.Random/3.3/RandomEnumerable.cs	(revision 14419)
+++ branches/ScopedBasicAlgorithm/HeuristicLab.Random/3.3/RandomEnumerable.cs	(revision 14420)
@@ -212,5 +212,5 @@
     }
 
-    private static double[] PrepareProportional(IEnumerable<double> weights, bool windowing, bool inverseProportional) {
+    public static double[] PrepareProportional(IEnumerable<double> weights, bool windowing, bool inverseProportional) {
       double maxValue = double.MinValue, minValue = double.MaxValue;
       double[] valueArray = weights.ToArray();
