Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/EvaluationResult.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/EvaluationResult.cs	(revision 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/EvaluationResult.cs	(revision 17381)
@@ -21,4 +21,5 @@
 
 using System.Collections.Generic;
+using System.Linq;
 using HEAL.Attic;
 using HeuristicLab.Common;
@@ -42,5 +43,6 @@
 
     protected EvaluationResult(EvaluationResult original, Cloner cloner) : base(original, cloner) {
-      //TODO clone data dictionary
+      data = original.data.ToDictionary(entry => entry.Key,
+                                        entry => entry.Value is DeepCloneable ? cloner.Clone((DeepCloneable)entry.Value) : entry.Value);
     }
 
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SingleObjectiveAnalyzer.cs	(revision 17381)
@@ -82,5 +82,4 @@
         var quality = ((DoubleValue)scope.Variables[QualityParameter.ActualName].Value).Value;
         var solutionContext = new SingleObjectiveSolutionContextScope<TEncodedSolution>(scope, solution);
-        solutionContext.EvaluationResult = new SingleObjectiveEvaluationResult(quality);
         return solutionContext;
       }).ToArray();
Index: branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SolutionContextScope.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SolutionContextScope.cs	(revision 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Operators/SolutionContextScope.cs	(revision 17381)
@@ -27,10 +27,12 @@
 //TODO: don't derive from NamedItem, this has been done to have a fast working prototype
 namespace HeuristicLab.Optimization {
-  internal class SolutionContextScope<TEncodedSolution> : SolutionContext<TEncodedSolution>, ISolutionScope
+  internal abstract class SolutionContextScope<TEncodedSolution> : SolutionContext<TEncodedSolution>, ISolutionScope
    where TEncodedSolution : class, IEncodedSolution {
-    private readonly IScope scope;
+    protected static string EVALUATION_RESULT_VARIABLE_NAME = "Evaluation Result";
+
+    protected IScope Scope { get; }
 
     public SolutionContextScope(IScope scope, TEncodedSolution solution) : base(solution) {
-      this.scope = scope;
+      Scope = scope;
     }
 
@@ -40,20 +42,18 @@
 
     IScope IScope.Parent {
-      get { return scope.Parent; }
+      get { return Scope.Parent; }
       set { throw new NotSupportedException(); }
     }
 
-    VariableCollection IScope.Variables => scope.Variables;
-    ScopeList IScope.SubScopes => scope.SubScopes;
+    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(); }
+    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(); }
+    string INamedItem.Description { get { return Scope.Description; } set => throw new NotImplementedException(); }
     bool INamedItem.CanChangeDescription => false;
 
@@ -78,5 +78,14 @@
     where TEncodedSolution : class, IEncodedSolution {
 
-    public new ISingleObjectiveEvaluationResult EvaluationResult { get; set; }
+    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) {
     }
@@ -86,5 +95,13 @@
   where TEncodedSolution : class, IEncodedSolution {
 
-    public new IMultiObjectiveEvaluationResult EvaluationResult { get; set; }
+    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 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/SolutionContext.cs	(revision 17381)
@@ -23,5 +23,5 @@
 using System;
 using System.Collections.Generic;
-
+using System.Linq;
 using HEAL.Attic;
 using HeuristicLab.Common;
@@ -58,7 +58,10 @@
 
     public SolutionContext(SolutionContext<TEncodedSolution> original, Cloner cloner) : base(original, cloner) {
-      //TODO clone data dictionary
       EncodedSolution = cloner.Clone(original.EncodedSolution);
       EvaluationResult = cloner.Clone(original.EvaluationResult);
+
+
+      data = original.data.ToDictionary(entry => entry.Key,
+                                        entry => entry.Value is DeepCloneable ? cloner.Clone((DeepCloneable)entry.Value) : entry.Value);
     }
 
Index: branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17381)
@@ -102,5 +102,5 @@
       : base(encoding) { }
 
-    #region ISingleObjectiveProblemDefinition<TEncoding,TEncodedSolution> Members
+    #region IMultiObjectiveProblemDefinition<TEncoding,TEncodedSolution> Members
     public int Objectives => Maximization.Length;
     public abstract bool[] Maximization { get; }
Index: branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/SingleObjectiveProblem_Template.cs
===================================================================
--- branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/SingleObjectiveProblem_Template.cs	(revision 17373)
+++ branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/SingleObjectiveProblem_Template.cs	(revision 17381)
@@ -21,8 +21,22 @@
     }
 
+    //TODO add other methods
+
+    public override void Evaluate(ISingleObjectiveSolutionContext<SOLUTION_CLASS> solutionContext, IRandom random, CancellationToken cancellationToken) {
+      var quality = Evaluate(solutionContext.EncodedSolution, random, cancellationToken);
+      var evaluationResult = new SingleObjectiveEvaluationResult(quality);
+      solutionContext.EvaluationResult = evaluationResult;
+    }
+
     public override double Evaluate(SOLUTION_CLASS solution, IRandom random, CancellationToken cancellationToken) {
       // Use vars.yourVariable to access variables in the variable store i.e. yourVariable
       var quality = 0.0;
       return quality;
+    }
+
+    public override void Analyze(ISingleObjectiveSolutionContext<TEncodedSolution>[] solutionContexts, ResultCollection results, IRandom random) {
+      var solutions = solutionContexts.Select(c => c.EncodedSolution).ToArray();
+      var qualities = solutionContexts.Select(c => c.EvaluationResult.Quality).ToArray();
+      Analyze(solutions, qualities, results, random);
     }
 
