Index: branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Encodings.BinaryVectorEncoding/3.3/BinaryVectorProblem.cs	(revision 17577)
@@ -71,8 +71,10 @@
 
     public override void Analyze(ISingleObjectiveSolutionContext<BinaryVector>[] solutionContexts, ResultCollection results, IRandom random) {
+      base.Analyze(solutionContexts, results, random);
       var best = GetBest(solutionContexts);
       var currentBest = BestResultParameter.ActualValue;
       if (currentBest == null || IsBetter(best.EvaluationResult.Quality, currentBest.EvaluationResult.Quality))
-        BestResultParameter.ActualValue = (ISingleObjectiveSolutionContext<BinaryVector>)best.Clone();
+        BestResultParameter.ActualValue = new SingleObjectiveSolutionContext<BinaryVector>(
+          (BinaryVector)best.EncodedSolution.Clone(), (ISingleObjectiveEvaluationResult)best.EvaluationResult.Clone());
     }
 
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISolutionContext.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISolutionContext.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/ISolutionContext.cs	(revision 17577)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HEAL.Attic;
 using HeuristicLab.Core;
@@ -29,4 +30,5 @@
 
     bool IsEvaluated { get; }
+    IEnumerable<KeyValuePair<string, object>> AdditionalData { get; }
     IEncodedSolution EncodedSolution { get; }
 
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/ScopeUtil.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/ScopeUtil.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/ScopeUtil.cs	(revision 17577)
@@ -28,5 +28,7 @@
 namespace HeuristicLab.Optimization {
   public static class ScopeUtil {
+    private const string EvaluationResultName = "EvaluationResult";
 
+    // TODO: Create SolutionContexts that derive from IScope to have a unified datastructure (e.g. #1614)
     public static TEncodedSolution CopyEncodedSolutionToScope<TEncodedSolution>(IScope scope, IEncoding<TEncodedSolution> encoding, TEncodedSolution solution)
       where TEncodedSolution : class, IEncodedSolution {
@@ -63,4 +65,31 @@
     }
 
+    public static ISingleObjectiveSolutionContext<TEncodedSolution> CreateSolutionContext<TEncodedSolution>(IScope scope, IEncoding<TEncodedSolution> encoding)
+      where TEncodedSolution : class, IEncodedSolution {
+      var solution = GetEncodedSolution(scope, encoding);
+      var context = new SingleObjectiveSolutionContext<TEncodedSolution>(solution);
+      foreach (var variable in scope.Variables) {
+        if (variable.Name != encoding.Name)
+          context.SetAdditionalData(variable.Name, variable.Value);
+      }
+      if (scope.Variables.TryGetValue(EvaluationResultName, out var variable2)) {
+        context.EvaluationResult = (ISingleObjectiveEvaluationResult)variable2.Value;
+      }
+      return context;
+    }
+
+    public static void CopyToScope<TEncodedSolution>(IScope scope, ISingleObjectiveSolutionContext<TEncodedSolution> solutionContext)
+      where TEncodedSolution : class, IEncodedSolution {
+      foreach (var item in solutionContext.AdditionalData) {
+        if (item.Value is IItem i) {
+          if (!scope.Variables.TryGetValue(item.Key, out var variable))
+            scope.Variables.Add(new Variable(item.Key, i));
+          else variable.Value = i;
+        }
+      }
+      if (!scope.Variables.TryGetValue(EvaluationResultName, out var variable2)) {
+        scope.Variables.Add(new Variable(EvaluationResultName, solutionContext.EvaluationResult));
+      } else variable2.Value = solutionContext.EvaluationResult;
+    }
   }
 }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 17577)
@@ -79,11 +79,11 @@
 
       var solutionContexts = scopes.Select(scope => {
-        var solution = ScopeUtil.GetEncodedSolution(scope, encoding);
-        var quality = ((DoubleValue)scope.Variables[QualityParameter.ActualName].Value).Value;
-        var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(scope, solution);
-        return solutionContext;
+        return ScopeUtil.CreateSolutionContext(scope, encoding);
       }).ToArray();
 
       Analyze(solutionContexts, results, random);
+      foreach (var s in solutionContexts.Zip(scopes, Tuple.Create)) {
+        ScopeUtil.CopyToScope(s.Item2, s.Item1);
+      }
       return base.Apply();
     }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveEvaluator.cs	(revision 17577)
@@ -63,11 +63,11 @@
       var random = RandomParameter.ActualValue;
       var encoding = EncodingParameter.ActualValue;
-      var solution = ScopeUtil.GetEncodedSolution(ExecutionContext.Scope, encoding);
-      var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(ExecutionContext.Scope, solution);
+      var solutionContext = ScopeUtil.CreateSolutionContext(ExecutionContext.Scope, encoding);
 
       Evaluate(solutionContext, random, CancellationToken.None);
-      var qualityValue = solutionContext.EvaluationResult.Quality;
+      
+      QualityParameter.ActualValue = new DoubleValue(solutionContext.EvaluationResult.Quality);
+      ScopeUtil.CopyToScope(ExecutionContext.Scope, solutionContext);
 
-      QualityParameter.ActualValue = new DoubleValue(qualityValue);
       return base.InstrumentedApply();
     }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveImprover.cs	(revision 17577)
@@ -90,6 +90,5 @@
       var maxAttempts = ImprovementAttemptsParameter.ActualValue.Value;
       var sampleSize = SampleSizeParameter.ActualValue.Value;
-      var solution = ScopeUtil.GetEncodedSolution(ExecutionContext.Scope, encoding);
-      var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(ExecutionContext.Scope, solution);
+      var solutionContext = ScopeUtil.CreateSolutionContext(ExecutionContext.Scope, encoding);
 
       double quality;
@@ -102,16 +101,17 @@
       var count = 0;
       for (var i = 0; i < maxAttempts; i++) {
-        TEncodedSolution best = default(TEncodedSolution);
+        ISingleObjectiveSolutionContext<TEncodedSolution> best = default;
         var bestQuality = quality;
         foreach (var neighbor in GetNeighbors(solutionContext, random).Take(sampleSize)) {
-          Evaluate(neighbor, random, CancellationToken);
+          if (!neighbor.IsEvaluated)
+            Evaluate(neighbor, random, CancellationToken);
           var q = neighbor.EvaluationResult.Quality;
           count++;
           if (maximize && bestQuality > q || !maximize && bestQuality < q) continue;
-          best = neighbor.EncodedSolution;
+          best = neighbor;
           bestQuality = q;
         }
         if (best == null) break;
-        solution = best;
+        solutionContext = best;
         quality = bestQuality;
       }
@@ -119,6 +119,6 @@
       LocalEvaluatedSolutionsParameter.ActualValue = new IntValue(count);
       QualityParameter.ActualValue = new DoubleValue(quality);
-
-      ScopeUtil.CopyEncodedSolutionToScope(ExecutionContext.Scope, encoding, solution);
+      ScopeUtil.CopyEncodedSolutionToScope(ExecutionContext.Scope, encoding, solutionContext.EncodedSolution);
+      ScopeUtil.CopyToScope(ExecutionContext.Scope, solutionContext);
       return base.Apply();
     }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveEvaluator.cs	(revision 17577)
@@ -70,11 +70,12 @@
       var random = RandomParameter.ActualValue;
       var encoding = EncodingParameter.ActualValue;
-      var solution = ScopeUtil.GetEncodedSolution(ExecutionContext.Scope, encoding);
-      var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(ExecutionContext.Scope, solution);
+      var solutionContext = ScopeUtil.CreateSolutionContext(ExecutionContext.Scope, encoding);
 
-      Evaluate(solutionContext, random, CancellationToken.None);
+      if (!solutionContext.IsEvaluated)
+        Evaluate(solutionContext, random, CancellationToken.None);
       var qualityValue = solutionContext.EvaluationResult.Quality;
 
       MoveQualityParameter.ActualValue = new DoubleValue(qualityValue);
+      ScopeUtil.CopyToScope(ExecutionContext.Scope, solutionContext);
       return base.Apply();
     }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveMoveGenerator.cs	(revision 17577)
@@ -68,6 +68,5 @@
       var sampleSize = SampleSizeParameter.ActualValue.Value;
       var encoding = EncodingParameter.ActualValue;
-      var solution = ScopeUtil.GetEncodedSolution(ExecutionContext.Scope, encoding);
-      var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(ExecutionContext.Scope, solution);
+      var solutionContext = ScopeUtil.CreateSolutionContext(ExecutionContext.Scope, encoding);
 
       var nbhood = GetNeighbors(solutionContext, random).Take(sampleSize).ToList();
@@ -76,4 +75,5 @@
         moveScopes[i] = new Scope(i.ToString(CultureInfo.InvariantCulture.NumberFormat));
         ScopeUtil.CopyEncodedSolutionToScope(moveScopes[i], encoding, nbhood[i].EncodedSolution);
+        ScopeUtil.CopyToScope(moveScopes[i], nbhood[i]);
       }
       ExecutionContext.Scope.SubScopes.AddRange(moveScopes);
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SolutionContextScope.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SolutionContextScope.cs	(revision 17573)
+++ 	(revision )
@@ -1,109 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 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;
-
-//TODO: don't derive from NamedItem, this has been done to have a fast working prototype
-namespace HeuristicLab.Optimization {
-  internal abstract class SolutionContextScope<TEncodedSolution> : SolutionContext<TEncodedSolution>, ISolutionScope
-   where TEncodedSolution : class, IEncodedSolution {
-    protected static string EVALUATION_RESULT_VARIABLE_NAME = "Evaluation Result";
-
-    protected IScope Scope { get; }
-
-    public SolutionContextScope(IScope scope, TEncodedSolution solution) : base(solution) {
-      Scope = scope;
-    }
-
-    public override IDeepCloneable Clone(Cloner cloner) {
-      throw new NotSupportedException();
-    }
-
-    IScope IScope.Parent {
-      get { return Scope.Parent; }
-      set { throw new NotSupportedException(); }
-    }
-
-    VariableCollection IScope.Variables => Scope.Variables;
-    ScopeList IScope.SubScopes => Scope.SubScopes;
-
-    void IScope.Clear() { throw new NotImplementedException(); }
-
-    #region INamedItem members
-    string INamedItem.Name { get { return Scope.Name; } set => throw new NotImplementedException(); }
-    bool INamedItem.CanChangeName => false;
-
-    string INamedItem.Description { get { return Scope.Description; } set => throw new NotImplementedException(); }
-    bool INamedItem.CanChangeDescription => false;
-
-    event EventHandler<CancelEventArgs<string>> INamedItem.NameChanging {
-      add { throw new NotImplementedException(); }
-      remove { throw new NotImplementedException(); }
-    }
-
-    event EventHandler INamedItem.NameChanged {
-      add { throw new NotImplementedException(); }
-      remove { throw new NotImplementedException(); }
-    }
-
-    event EventHandler INamedItem.DescriptionChanged {
-      add { throw new NotImplementedException(); }
-      remove { throw new NotImplementedException(); }
-    }
-    #endregion
-  }
-
-  internal class SingleObjectiveSolutionContextScope<TEncodedSolution> : SolutionContextScope<TEncodedSolution>, ISingleObjectiveSolutionScope<TEncodedSolution>
-    where TEncodedSolution : class, IEncodedSolution {
-
-    public new ISingleObjectiveEvaluationResult EvaluationResult {
-      get {
-        return (ISingleObjectiveEvaluationResult)Scope.Variables[EVALUATION_RESULT_VARIABLE_NAME].Value;
-      }
-      set {
-        Scope.Variables.Remove(EVALUATION_RESULT_VARIABLE_NAME);
-        Scope.Variables.Add(new Variable(EVALUATION_RESULT_VARIABLE_NAME, value));
-      }
-    }
-
-    public SingleObjectiveSolutionContextScope(IScope scope, TEncodedSolution solution) : base(scope, solution) {
-    }
-  }
-
-  internal class MultiObjectiveSolutionContextScope<TEncodedSolution> : SolutionContextScope<TEncodedSolution>, IMultiObjectiveSolutionScope<TEncodedSolution>
-  where TEncodedSolution : class, IEncodedSolution {
-
-    public new IMultiObjectiveEvaluationResult EvaluationResult {
-      get {
-        return (IMultiObjectiveEvaluationResult)Scope.Variables[EVALUATION_RESULT_VARIABLE_NAME].Value;
-      }
-      set {
-        Scope.Variables.Remove(EVALUATION_RESULT_VARIABLE_NAME);
-        Scope.Variables.Add(new Variable(EVALUATION_RESULT_VARIABLE_NAME, value));
-      }
-    }
-    public MultiObjectiveSolutionContextScope(IScope scope, TEncodedSolution solution) : base(scope, solution) {
-    }
-  }
-}
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/SolutionContext.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/SolutionContext.cs	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/SolutionContext.cs	(revision 17577)
@@ -35,4 +35,5 @@
     [Storable]
     private readonly Dictionary<string, object> data = new Dictionary<string, object>();
+    public IEnumerable<KeyValuePair<string, object>> AdditionalData { get { return data; } }
 
     IEncodedSolution ISolutionContext.EncodedSolution { get { return EncodedSolution; } }
@@ -77,5 +78,8 @@
   public class SingleObjectiveSolutionContext<TEncodedSolution> : SolutionContext<TEncodedSolution>, ISingleObjectiveSolutionContext<TEncodedSolution>
    where TEncodedSolution : class, IEncodedSolution {
-    public new ISingleObjectiveEvaluationResult EvaluationResult { get; set; }
+    public new ISingleObjectiveEvaluationResult EvaluationResult {
+      get { return (ISingleObjectiveEvaluationResult)base.EvaluationResult; }
+      set { base.EvaluationResult = value; }
+    }
 
     public SingleObjectiveSolutionContext(TEncodedSolution encodedSolution) : base(encodedSolution) { }
@@ -98,5 +102,8 @@
   public class MultiObjectiveSolutionContext<TEncodedSolution> : SolutionContext<TEncodedSolution>, IMultiObjectiveSolutionContext<TEncodedSolution>
    where TEncodedSolution : class, IEncodedSolution {
-    public new IMultiObjectiveEvaluationResult EvaluationResult { get; set; }
+    public new IMultiObjectiveEvaluationResult EvaluationResult {
+      get { return (IMultiObjectiveEvaluationResult)base.EvaluationResult; }
+      set { base.EvaluationResult = value; }
+    }
 
     public MultiObjectiveSolutionContext(TEncodedSolution encodedSolution) : base(encodedSolution) { }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 17573)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/HeuristicLab.Optimization-3.3.csproj	(revision 17577)
@@ -134,5 +134,4 @@
     <Compile Include="BasicProblems\Operators\MultiEncodingManipulator.cs" />
     <Compile Include="BasicProblems\Operators\MultiEncodingOperator.cs" />
-    <Compile Include="BasicProblems\Operators\SolutionContextScope.cs" />
     <Compile Include="BasicProblems\Problem.cs" />
     <Compile Include="BasicProblems\Encoding.cs" />
