Index: branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs	(revision 13551)
+++ branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/CharacteristicCalculator.cs	(revision 13594)
@@ -20,29 +20,40 @@
 #endregion
 
-using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using System.Collections.Generic;
 
 namespace HeuristicLab.Problems.CharacteristicAnalysis {
   [Item("Characteristic Calculator", "")]
   [StorableClass]
-  public abstract class CharacteristicCalculator : NamedItem, ICharacteristicCalculator {
+  public abstract class CharacteristicCalculator : ParameterizedNamedItem, ICharacteristicCalculator {
 
-    public abstract IEnumerable<string> Characteristics { get; }
+    [Storable]
+    public IProblem Problem { get; set; }
+
+    [Storable]
+    protected CheckedItemList<StringValue> characteristics;
+    public ReadOnlyCheckedItemList<StringValue> Characteristics { get { return characteristics.AsReadOnly(); } }
 
     [StorableConstructor]
     protected CharacteristicCalculator(bool deserializing) : base(deserializing) { }
-    protected CharacteristicCalculator(CharacteristicCalculator original, Cloner cloner) : base(original, cloner) { }
+    protected CharacteristicCalculator(CharacteristicCalculator original, Cloner cloner)
+      : base(original, cloner) {
+      characteristics = cloner.Clone(original.characteristics);
+      Problem = cloner.Clone(original.Problem);
+    }
     protected CharacteristicCalculator()
       : base() {
       name = ItemName;
       description = ItemDescription;
+      characteristics = new CheckedItemList<StringValue>();
     }
 
-    public abstract bool CanCalculate(IProblem problem);
+    public abstract bool CanCalculate();
 
-    public abstract IEnumerable<KeyValuePair<string, IItem>> Calculate(IProblem problem, IEnumerable<string> characteristics = null);
+    public abstract IEnumerable<IResult> Calculate();
   }
 }
Index: branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs
===================================================================
--- branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs	(revision 13551)
+++ branches/PerformanceComparison/HeuristicLab.OptimizationExpertSystem/3.3/ProblemCharacteristicAnalysis/QAP/QAPCharacteristicCalculator.cs	(revision 13594)
@@ -20,11 +20,13 @@
 #endregion
 
-using System;
-using System.Collections.Generic;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.Problems.QuadraticAssignment;
+using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace HeuristicLab.Problems.CharacteristicAnalysis.QAP {
@@ -33,19 +35,15 @@
   public sealed class QAPCharacteristicCalculator : CharacteristicCalculator {
 
-    public override IEnumerable<string> Characteristics {
-      get {
-        return new[] { "Dimension",
+    [StorableConstructor]
+    private QAPCharacteristicCalculator(bool deserializing) : base(deserializing) { }
+    private QAPCharacteristicCalculator(QAPCharacteristicCalculator original, Cloner cloner) : base(original, cloner) { }
+    public QAPCharacteristicCalculator() {
+      characteristics.AddRange(new[] { "Dimension",
         "FlowDominance", "DistanceDominance",
         "FlowAsymmetry", "DistanceAsymmetry",
         "FlowSparsity", "DistanceSparsity",
         "FlowSkewness", "DistanceSkewness",
-        "FlowDisparity", "DistanceDisparity" };
-      }
+        "FlowDisparity", "DistanceDisparity" }.Select(x => new StringValue(x)).ToList());
     }
-
-    [StorableConstructor]
-    private QAPCharacteristicCalculator(bool deserializing) : base(deserializing) { }
-    private QAPCharacteristicCalculator(QAPCharacteristicCalculator original, Cloner cloner) : base(original, cloner) { }
-    public QAPCharacteristicCalculator() { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -53,34 +51,35 @@
     }
 
-    public override bool CanCalculate(IProblem problem) {
-      return problem is QuadraticAssignmentProblem;
+    public override bool CanCalculate() {
+      return Problem is QuadraticAssignmentProblem;
     }
 
-    public override IEnumerable<KeyValuePair<string, IItem>> Calculate(IProblem problem, IEnumerable<string> characteristics = null) {
-      var qap = problem as QuadraticAssignmentProblem;
-      if (qap == null) throw new ArgumentException("Instance is not of type QuadraticAssignmentProblem", "problem");
-      var allowed = new HashSet<string>(characteristics ?? Characteristics);
-      if (allowed.Contains("Dimension"))
-        yield return new KeyValuePair<string, IItem>("Dimension", new Data.IntValue(qap.Weights.Rows));
-      if (allowed.Contains("FlowDominance"))
-        yield return new KeyValuePair<string, IItem>("FlowDominance", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Weights)));
-      if (allowed.Contains("DistanceDominance"))
-        yield return new KeyValuePair<string, IItem>("DistanceDominance", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Distances)));
-      if (allowed.Contains("FlowAsymmetry"))
-        yield return new KeyValuePair<string, IItem>("FlowAsymmetry", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Weights)));
-      if (allowed.Contains("DistanceAsymmetry"))
-        yield return new KeyValuePair<string, IItem>("DistanceAsymmetry", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Distances)));
-      if (allowed.Contains("FlowSparsity"))
-        yield return new KeyValuePair<string, IItem>("FlowSparsity", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Weights)));
-      if (allowed.Contains("DistanceSparsity"))
-        yield return new KeyValuePair<string, IItem>("DistanceSparsity", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Distances)));
-      if (allowed.Contains("FlowSkewness"))
-        yield return new KeyValuePair<string, IItem>("FlowSkewness", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Weights)));
-      if (allowed.Contains("DistanceSkewness"))
-        yield return new KeyValuePair<string, IItem>("DistanceSkewness", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Distances)));
-      if (allowed.Contains("FlowDisparity"))
-        yield return new KeyValuePair<string, IItem>("FlowDisparity", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Weights)));
-      if (allowed.Contains("DistanceDisparity"))
-        yield return new KeyValuePair<string, IItem>("DistanceDisparity", new Data.DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Distances)));
+    public override IEnumerable<IResult> Calculate() {
+      var qap = Problem as QuadraticAssignmentProblem;
+      if (qap == null) throw new ArgumentException("Instance is not of type QuadraticAssignmentProblem");
+      foreach (var chara in characteristics.CheckedItems.Select(x => x.Value.Value)) {
+        if (chara == "Dimension")
+          yield return new Result(chara, new IntValue(qap.Weights.Rows));
+        if (chara == "FlowDominance")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Weights)));
+        if (chara == "DistanceDominance")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariation(qap.Distances)));
+        if (chara == "FlowAsymmetry")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Weights)));
+        if (chara == "DistanceAsymmetry")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Asymmetry(qap.Distances)));
+        if (chara == "FlowSparsity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Weights)));
+        if (chara == "DistanceSparsity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(qap.Distances)));
+        if (chara == "FlowSkewness")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Weights)));
+        if (chara == "DistanceSkewness")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Skewness(qap.Distances)));
+        if (chara == "FlowDisparity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Weights)));
+        if (chara == "DistanceDisparity")
+          yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Disparity(qap.Distances)));
+      }
     }
   }
