Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/CplexSolver.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/CplexSolver.cs	(revision 15574)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/CplexSolver.cs	(revision 15575)
@@ -59,12 +59,4 @@
     }
 
-    protected override void Initialize(CancellationToken cancellationToken) {
-      base.Initialize(cancellationToken);
-
-      try {
-        Context.RunOperator(Analyzer, cancellationToken);
-      } catch (OperationCanceledException) { }
-    }
-
     protected override void Run(CancellationToken cancellationToken) {
       var factory = new OplFactory();
@@ -100,5 +92,5 @@
       if (HasIncumbent()) {
         var val = GetIncumbentObjValue();
-        if (val == prev) return;
+        if (val >= prev) return;
         algorithm.Context.Iterations++;
         algorithm.Context.BestQuality = val;
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-FY.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-FY.cs	(revision 15574)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-FY.cs	(revision 15575)
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-KB.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-KB.cs	(revision 15574)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/CPLEX/GQAP-KB.cs	(revision 15575)
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms-3.3.csproj
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms-3.3.csproj	(revision 15574)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms-3.3.csproj	(revision 15575)
@@ -32,5 +32,5 @@
   </PropertyGroup>
   <PropertyGroup>
-    <SignAssembly>true</SignAssembly>
+    <SignAssembly>false</SignAssembly>
   </PropertyGroup>
   <PropertyGroup>
@@ -38,5 +38,6 @@
   </PropertyGroup>
   <PropertyGroup>
-    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+    <AssemblyOriginatorKeyFile>
+    </AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
@@ -133,4 +134,7 @@
     <Compile Include="LocalSearch\IteratedLS.cs" />
     <Compile Include="LocalSearch\MultistartLS.cs" />
+    <Compile Include="LocalSolverNet\GQAPIntegerSolver.cs" />
+    <Compile Include="LocalSolverNet\LocalSolverContext.cs" />
+    <Compile Include="LocalSolverNet\GQAPBinarySolver.cs" />
     <Compile Include="Plugin.cs" />
     <Compile Include="Infrastructure\Contexts\SingleSolutionContext.cs" />
@@ -156,7 +160,4 @@
     </ProjectReference>
   </ItemGroup>
-  <ItemGroup>
-    <None Include="HeuristicLab.snk" />
-  </ItemGroup>
   <ItemGroup />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPBinarySolver.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPBinarySolver.cs	(revision 15575)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPBinarySolver.cs	(revision 15575)
@@ -0,0 +1,212 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using localsolver;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LocalSolverNet {
+  [Item("LocalSolver Binary (GQAP)", "LocalSolver algorithm solving the GQAP using 0-1 decision variables")]
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.Algorithms)]
+  public sealed class GQAPBinarySolver : ContextAlgorithm<LocalSolverContext, IntegerVectorEncoding> {
+    public override bool SupportsPause {
+      get { return false; }
+    }
+
+    public override Type ProblemType {
+      get { return typeof(GQAP); }
+    }
+
+    public new GQAP Problem {
+      get { return (GQAP)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    // LS Program variables
+    private LSExpression[][] x;
+    private LSExpression[] equipmentsOnLocations;
+    private LSExpression obj;
+    private LocalSolver localSolver;
+
+
+    [StorableConstructor]
+    private GQAPBinarySolver(bool deserializing) : base(deserializing) { }
+    private GQAPBinarySolver(GQAPBinarySolver original, Cloner cloner)
+    : base(original, cloner) {
+    }
+    public GQAPBinarySolver() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPBinarySolver(this, cloner);
+    }
+
+    private double prevObj;
+    private DateTime lastUpdate;
+    private CancellationToken token;
+
+    private void LocalSolverOnIterationTicked(LocalSolver ls, LSCallbackType type) {
+      IResult result;
+      Context.Iterations++;
+      if ((DateTime.UtcNow - lastUpdate) > TimeSpan.FromSeconds(1)) {
+        if (Results.TryGetValue("Iterations", out result))
+          ((IntValue)result.Value).Value = Context.Iterations;
+        else Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+        lastUpdate = DateTime.UtcNow;
+      }
+
+      if (token.IsCancellationRequested) localSolver.Stop();
+
+      var curObj = obj.GetDoubleValue();
+
+      if (curObj >= prevObj) return;
+      prevObj = curObj;
+      Context.BestQuality = curObj;
+           
+      if (Results.TryGetValue("BestQuality", out result))
+        ((DoubleValue)result.Value).Value = Context.BestQuality;
+      else Results.Add(new Result("BestQuality", new DoubleValue(Context.BestQuality)));
+
+      var locations = Problem.ProblemInstance.Capacities.Length;
+      var best = new int[Problem.ProblemInstance.Demands.Length];
+      for (var i = 0; i < best.Length; i++) {
+        for (var j = 0; j < locations; j++) {
+          if (x[i][j].GetIntValue() == 1) {
+            best[i] = j;
+            break;
+          }
+        }
+      }
+      var bestVec = new IntegerVector(best);
+      var eval = Problem.ProblemInstance.Evaluate(bestVec);
+      Context.BestSolution = new GQAPSolution(bestVec, eval);
+
+      var scope = Context.ToScope(new GQAPSolution(new IntegerVector(best), (Evaluation)eval.Clone()), Problem.ProblemInstance.ToSingleObjective(eval));
+      Context.ReplaceIncumbent(scope);
+
+      if (Results.TryGetValue("BestSolution", out result))
+        result.Value = Context.BestSolution;
+      else Results.Add(new Result("BestSolution", Context.BestSolution));
+
+      Context.RunOperator(Analyzer, CancellationToken.None);
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+
+      prevObj = double.MaxValue;
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      token = cancellationToken;
+      lastUpdate = DateTime.UtcNow.AddSeconds(-1);
+      localSolver = new LocalSolver();
+
+      // Declares the optimization model
+      LSModel model = localSolver.GetModel();
+
+      var data = Problem.ProblemInstance;
+
+      // x[f,l] = 1 if equipments f is on location l, 0 otherwise
+      x = new LSExpression[data.Demands.Length][];
+      for (int f = 0; f < data.Demands.Length; f++) {
+        x[f] = new LSExpression[data.Capacities.Length];
+        for (int l = 0; l < data.Capacities.Length; l++) {
+          x[f][l] = model.Bool();
+        }
+      }
+
+      // All equipments are installed in exactly 1 location
+      for (int f = 0; f < data.Demands.Length; f++) {
+        LSExpression nbLocationsAssigned = model.Sum();
+        for (int l = 0; l < data.Capacities.Length; l++) {
+          nbLocationsAssigned.AddOperand(x[f][l]);
+        }
+        model.Constraint(nbLocationsAssigned == 1);
+      }
+
+      // All locations contain not more equipments than there is capacity for
+      for (int l = 0; l < data.Capacities.Length; l++) {
+        LSExpression assignedDemand = model.Sum();
+        for (int f = 0; f < data.Demands.Length; f++) {
+          assignedDemand.AddOperand(x[f][l] * data.Demands[f]);
+        }
+        model.Constraint(assignedDemand <= data.Capacities[l]);
+      }
+
+      // Index of the assigned location of equipment f
+      equipmentsOnLocations = new LSExpression[data.Demands.Length];
+      for (int f = 0; f < data.Demands.Length; f++) {
+        equipmentsOnLocations[f] = model.Sum();
+        for (int l = 0; l < data.Capacities.Length; l++) {
+          equipmentsOnLocations[f].AddOperand(l * x[f][l]);
+        }
+      }
+
+      // Create distances as an array to be accessed by an at operator
+      var distancesJagged = new double[data.Capacities.Length][];
+      for (var i = 0; i < data.Capacities.Length; i++) {
+        distancesJagged[i] = new double[data.Capacities.Length];
+        for (var j = 0; j < data.Capacities.Length; j++)
+          distancesJagged[i][j] = data.Distances[i, j];
+      }
+      var installJagged = new double[data.Demands.Length][];
+      for (var i = 0; i < data.Demands.Length; i++) {
+        installJagged[i] = new double[data.Capacities.Length];
+        for (var j = 0; j < data.Capacities.Length; j++)
+          installJagged[i][j] = data.InstallationCosts[i, j];
+      }
+      LSExpression distancesArray = model.Array(distancesJagged);
+      LSExpression installCostsArray = model.Array(installJagged);
+
+      // Minimize the sum of product distance*flow
+      obj = model.Sum();
+      for (int f1 = 0; f1 < data.Demands.Length; f1++) {
+        for (int f2 = 0; f2 < data.Demands.Length; f2++) {
+          obj.AddOperand(data.TransportationCosts * data.Weights[f1, f2] * distancesArray[equipmentsOnLocations[f1], equipmentsOnLocations[f2]]);
+        }
+        obj.AddOperand(installCostsArray[f1, equipmentsOnLocations[f1]]);
+      }
+
+      model.Minimize(obj);
+
+      model.Close();
+
+      // Parameterizes the solver.
+      LSPhase phase = localSolver.CreatePhase();
+      phase.SetTimeLimit((int)Math.Ceiling(MaximumRuntime.TotalSeconds));
+
+      localSolver.AddCallback(LSCallbackType.IterationTicked, LocalSolverOnIterationTicked);
+      
+      localSolver.Solve();
+
+      localSolver.RemoveCallback(LSCallbackType.IterationTicked, LocalSolverOnIterationTicked);
+      localSolver.Dispose();
+    }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPIntegerSolver.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPIntegerSolver.cs	(revision 15575)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/GQAPIntegerSolver.cs	(revision 15575)
@@ -0,0 +1,185 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Threading;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Encodings.IntegerVectorEncoding;
+using HeuristicLab.Optimization;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using localsolver;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LocalSolverNet {
+  [Item("LocalSolver Integer (GQAP)", "LocalSolver algorithm solving the GQAP using integer decision variables")]
+  [StorableClass]
+  [Creatable(CreatableAttribute.Categories.Algorithms)]
+  public sealed class GQAPIntegerSolver : ContextAlgorithm<LocalSolverContext, IntegerVectorEncoding> {
+    public override bool SupportsPause {
+      get { return false; }
+    }
+
+    public override Type ProblemType {
+      get { return typeof(GQAP); }
+    }
+
+    public new GQAP Problem {
+      get { return (GQAP)base.Problem; }
+      set { base.Problem = value; }
+    }
+
+    // LS Program variables
+    private LSExpression[] x;
+    private LSExpression obj;
+    private LocalSolver localSolver;
+
+
+    [StorableConstructor]
+    private GQAPIntegerSolver(bool deserializing) : base(deserializing) { }
+    private GQAPIntegerSolver(GQAPIntegerSolver original, Cloner cloner)
+    : base(original, cloner) {
+    }
+    public GQAPIntegerSolver() {
+    }
+
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new GQAPIntegerSolver(this, cloner);
+    }
+
+    private double prevObj;
+    private DateTime lastUpdate;
+    private CancellationToken token;
+
+    private void LocalSolverOnIterationTicked(LocalSolver ls, LSCallbackType type) {
+      IResult result;
+      Context.Iterations++;
+      if ((DateTime.UtcNow - lastUpdate) > TimeSpan.FromSeconds(1)) {
+        if (Results.TryGetValue("Iterations", out result))
+          ((IntValue)result.Value).Value = Context.Iterations;
+        else Results.Add(new Result("Iterations", new IntValue(Context.Iterations)));
+        lastUpdate = DateTime.UtcNow;
+      }
+
+      if (token.IsCancellationRequested) localSolver.Stop();
+
+      var curObj = obj.GetDoubleValue();
+
+      if (curObj >= prevObj) return;
+      prevObj = curObj;
+      Context.BestQuality = curObj;
+           
+      if (Results.TryGetValue("BestQuality", out result))
+        ((DoubleValue)result.Value).Value = Context.BestQuality;
+      else Results.Add(new Result("BestQuality", new DoubleValue(Context.BestQuality)));
+
+      var locations = Problem.ProblemInstance.Capacities.Length;
+      var best = new int[Problem.ProblemInstance.Demands.Length];
+      for (var i = 0; i < best.Length; i++) {
+        best[i] = (int)x[i].GetIntValue();
+      }
+      var bestVec = new IntegerVector(best);
+      var eval = Problem.ProblemInstance.Evaluate(bestVec);
+      Context.BestSolution = new GQAPSolution(bestVec, eval);
+
+      var scope = Context.ToScope(new GQAPSolution(new IntegerVector(best), (Evaluation)eval.Clone()), Problem.ProblemInstance.ToSingleObjective(eval));
+      Context.ReplaceIncumbent(scope);
+
+      if (Results.TryGetValue("BestSolution", out result))
+        result.Value = Context.BestSolution;
+      else Results.Add(new Result("BestSolution", Context.BestSolution));
+
+      Context.RunOperator(Analyzer, CancellationToken.None);
+    }
+
+    protected override void Initialize(CancellationToken cancellationToken) {
+      base.Initialize(cancellationToken);
+
+      prevObj = double.MaxValue;
+    }
+
+    protected override void Run(CancellationToken cancellationToken) {
+      token = cancellationToken;
+      lastUpdate = DateTime.UtcNow.AddSeconds(-1);
+      localSolver = new LocalSolver();
+
+      // Declares the optimization model
+      LSModel model = localSolver.GetModel();
+
+      var data = Problem.ProblemInstance;
+
+      // x[f] = location l, f ... facility/equipment
+      x = new LSExpression[data.Demands.Length];
+      for (int f = 0; f < data.Demands.Length; f++) {
+        x[f] = model.Int(0, data.Capacities.Length - 1);
+      }
+
+      // All locations contain not more equipments than there is capacity for
+      for (int l = 0; l < data.Capacities.Length; l++) {
+        var util = model.Sum();
+        for (var f = 0; f < data.Demands.Length; f++)
+          util.AddOperand((x[f] == l) * data.Demands[f]);
+        model.Constraint(util <= data.Capacities[l]);
+      }
+
+      // Create distances as an array to be accessed by an at operator
+      var distancesJagged = new double[data.Capacities.Length][];
+      for (var i = 0; i < data.Capacities.Length; i++) {
+        distancesJagged[i] = new double[data.Capacities.Length];
+        for (var j = 0; j < data.Capacities.Length; j++)
+          distancesJagged[i][j] = data.Distances[i, j];
+      }
+      var installJagged = new double[data.Demands.Length][];
+      for (var i = 0; i < data.Demands.Length; i++) {
+        installJagged[i] = new double[data.Capacities.Length];
+        for (var j = 0; j < data.Capacities.Length; j++)
+          installJagged[i][j] = data.InstallationCosts[i, j];
+      }
+      LSExpression distancesArray = model.Array(distancesJagged);
+      LSExpression installCostsArray = model.Array(installJagged);
+
+      // Minimize the sum of product distance*flow
+      obj = model.Sum();
+      for (int f1 = 0; f1 < data.Demands.Length; f1++) {
+        for (int f2 = 0; f2 < data.Demands.Length; f2++) {
+          obj.AddOperand(data.TransportationCosts * data.Weights[f1, f2] * distancesArray[x[f1], x[f2]]);
+        }
+        obj.AddOperand(installCostsArray[f1, x[f1]]);
+      }
+
+      model.Minimize(obj);
+
+      try {
+        model.Close();
+
+        // Parameterizes the solver.
+        LSPhase phase = localSolver.CreatePhase();
+        phase.SetTimeLimit((int)Math.Ceiling(MaximumRuntime.TotalSeconds));
+
+        localSolver.AddCallback(LSCallbackType.IterationTicked, LocalSolverOnIterationTicked);
+
+        localSolver.Solve();
+      } finally {
+        localSolver.Dispose();
+      }
+    }
+  }
+}
Index: branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/LocalSolverContext.cs
===================================================================
--- branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/LocalSolverContext.cs	(revision 15575)
+++ branches/GeneralizedQAP/HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms/3.3/LocalSolverNet/LocalSolverContext.cs	(revision 15575)
@@ -0,0 +1,88 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2017 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Parameters;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.GeneralizedQuadraticAssignment.Algorithms.LocalSolverNet {
+  [Item("LocalSolver Context", "A context for CPLEX solvers.")]
+  public class LocalSolverContext : SingleSolutionContext<ISingleObjectiveSolutionScope<GQAPSolution>> {
+
+    [Storable]
+    private IValueParameter<GQAP> problem;
+    public GQAP Problem {
+      get { return problem.Value; }
+      set { problem.Value = value; }
+    }
+
+    [Storable]
+    private IValueParameter<GQAPSolution> bestSolution;
+    public GQAPSolution BestSolution {
+      get { return bestSolution.Value; }
+      set { bestSolution.Value = value; }
+    }
+
+    [StorableConstructor]
+    protected LocalSolverContext(bool deserializing) : base(deserializing) { }
+    protected LocalSolverContext(LocalSolverContext original, Cloner cloner)
+      : base(original, cloner) {
+      problem = cloner.Clone(original.problem);
+      bestSolution = cloner.Clone(original.bestSolution);
+    }
+    public LocalSolverContext() : base() {
+      Parameters.Add(problem = new ValueParameter<GQAP>("Problem"));
+      Parameters.Add(bestSolution = new ValueParameter<GQAPSolution>("BestFoundSolution"));
+    }
+    public LocalSolverContext(string name) : base(name) {
+      Parameters.Add(problem = new ValueParameter<GQAP>("Problem"));
+      Parameters.Add(bestSolution = new ValueParameter<GQAPSolution>("BestFoundSolution"));
+    }
+    public LocalSolverContext(string name, ParameterCollection parameters) : base(name, parameters) {
+      Parameters.Add(problem = new ValueParameter<GQAP>("Problem"));
+      Parameters.Add(bestSolution = new ValueParameter<GQAPSolution>("BestFoundSolution"));
+    }
+    public LocalSolverContext(string name, string description) : base(name, description) {
+      Parameters.Add(problem = new ValueParameter<GQAP>("Problem"));
+      Parameters.Add(bestSolution = new ValueParameter<GQAPSolution>("BestFoundSolution"));
+    }
+    public LocalSolverContext(string name, string description, ParameterCollection parameters) : base(name, description, parameters) {
+      Parameters.Add(problem = new ValueParameter<GQAP>("Problem"));
+      Parameters.Add(bestSolution = new ValueParameter<GQAPSolution>("BestFoundSolution"));
+    }
+    
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new LocalSolverContext(this, cloner);
+    }
+
+    public ISingleObjectiveSolutionScope<GQAPSolution> ToScope(GQAPSolution code, double fitness = double.NaN) {
+      var name = Problem.Encoding.Name;
+      var scope = new SingleObjectiveSolutionScope<GQAPSolution>(code,
+        name + "Solution", fitness, Problem.Evaluator.QualityParameter.ActualName) {
+        Parent = Scope
+      };
+      scope.Variables.Add(new Variable(name, code.Assignment));
+      scope.Variables.Add(new Variable("Evaluation", code.Evaluation));
+      return scope;
+    }
+  }
+}
