Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/Indicators/HypervolumeIndicator.cs	(revision 17309)
@@ -26,5 +26,4 @@
 using HeuristicLab.Core;
 using HeuristicLab.Optimization;
-using HeuristicLab.Problems.TestFunctions.MultiObjective;
 
 namespace HeuristicLab.Algorithms.MOCMAEvolutionStrategy {
@@ -53,5 +52,5 @@
 
     #region Helpers
-    private static double Contribution(IList<double[]> front, int idx, bool[] maximization, double[] refPoint) {
+    private static double Contribution(IList<double[]> front, int idx, IReadOnlyList<bool> maximization, double[] refPoint) {
       var point = front[idx];
       front.RemoveAt(idx);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Algorithms.MOCMAEvolutionStrategy/3.3/MOCMAEvolutionStrategy.cs	(revision 17309)
@@ -376,5 +376,5 @@
       var bkf = problem.BestKnownFront == null ? null : problem.BestKnownFront.ToArray();
       if (bkf != null && problem.ReferencePoint != null) {
-        ResultsBestKnownHypervolume = HypervolumeCalculator.CalculateHypervolume(bkf, problem.ReferencePoint, Problem.Maximization);
+        ResultsBestKnownHypervolume = HypervolumeCalculator.CalculateHypervolume(bkf, problem.ReferencePoint, Problem.Maximization.CloneAsArray());
         ResultsDifferenceBestKnownHypervolume = ResultsBestKnownHypervolume;
       }
@@ -456,5 +456,5 @@
       //perform a non-dominated sort to assign the rank to every element
       int[] ranks;
-      var fronts = DominationCalculator.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization, out ranks);
+      var fronts = DominationCalculator.CalculateAllParetoFronts(parents.ToArray(), parents.Select(i => i.PenalizedFitness).ToArray(), Problem.Maximization.CloneAsArray(), out ranks);
 
       //deselect the highest rank fronts until we would end up with less or equal mu elements
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/BoolArray.cs	(revision 17309)
@@ -20,4 +20,5 @@
 #endregion
 
+using System.Collections.Generic;
 using System.Text;
 using HEAL.Attic;
@@ -37,4 +38,5 @@
     public BoolArray(int length) : base(length) { }
     public BoolArray(bool[] elements, bool @readonly = false) : base(elements, @readonly) { }
+    public BoolArray(IReadOnlyList<bool> elements) : base(elements) { }
 
     public override IDeepCloneable Clone(Cloner cloner) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/StringConvertibleArray.cs	(revision 17309)
@@ -22,4 +22,5 @@
 #endregion
 
+using System.Collections.Generic;
 using HEAL.Attic;
 using HeuristicLab.Common;
@@ -38,4 +39,5 @@
     protected StringConvertibleArray(int length) : base(length) { }
     protected StringConvertibleArray(T[] elements, bool @readonly = false) : base(elements, @readonly) { }
+    protected StringConvertibleArray(IReadOnlyList<T> elements) : base(elements) { }
 
     protected abstract bool Validate(string value, out string errorMessage);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Data/3.3/ValueTypeArray.cs	(revision 17309)
@@ -138,9 +138,17 @@
     }
     protected ValueTypeArray(T[] elements, bool @readonly = false) {
-      if (elements == null) throw new ArgumentNullException();
+      if (elements == null) throw new ArgumentNullException(nameof(elements));
       array = (T[])elements.Clone();
       readOnly = @readonly;
       resizable = true;
       elementNames = new List<string>();
+    }
+    
+    protected ValueTypeArray(IReadOnlyList<T> elements) {
+      if (elements == null) throw new ArgumentNullException(nameof(elements));
+      array = elements.ToArray(); // TODO: array should be an IList<T>
+      readOnly = true;
+      resizable = true; // TODO: really?
+      elementNames = new List<string>(); // TODO: wasteful
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMultiObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMultiObjectiveProblem.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Encodings.SymbolicExpressionTreeEncoding/3.4/SymbolicExpressionTreeMultiObjectiveProblem.cs	(revision 17309)
@@ -54,5 +54,5 @@
       base.Analyze(trees, qualities, results, random);
 
-      var fronts = DominationCalculator.CalculateAllParetoFrontsIndices(trees, qualities, Maximization);
+      var fronts = DominationCalculator.CalculateAllParetoFrontsIndices(trees, qualities, Maximization.CloneAsArray());
       var plot = new ParetoFrontScatterPlot<ISymbolicExpressionTree>(fronts, trees, qualities, Objectives, BestKnownFront);
       results.AddOrUpdateResult("Pareto Front Scatter Plot", plot);
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/Interfaces/IMultiObjectiveProblemDefinition.cs	(revision 17309)
@@ -28,5 +28,5 @@
   public interface IMultiObjectiveProblemDefinition {
     int Objectives { get; }
-    bool[] Maximization { get; }
+    IReadOnlyList<bool> Maximization { get; }
     IReadOnlyList<double[]> BestKnownFront { get; }
     double[] ReferencePoint { get; }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/BasicProblems/MultiObjectiveProblem.cs	(revision 17309)
@@ -37,5 +37,4 @@
     where TEncodedSolution : class, IEncodedSolution {
     #region Parameternames
-    public const string MaximizationParameterName = "Maximization";
     public const string BestKnownFrontParameterName = "BestKnownFront";
     public const string ReferencePointParameterName = "ReferencePoint";
@@ -43,7 +42,5 @@
 
     #region Parameterproperties
-    public IValueParameter<BoolArray> MaximizationParameter {
-      get { return (IValueParameter<BoolArray>)Parameters[MaximizationParameterName]; }
-    }
+    [Storable] protected IValueParameter<BoolArray> MaximizationParameter { get; }
     public IValueParameter<DoubleMatrix> BestKnownFrontParameter {
       get { return (IValueParameter<DoubleMatrix>)Parameters[BestKnownFrontParameterName]; }
@@ -60,9 +57,11 @@
     protected MultiObjectiveProblem(MultiObjectiveProblem<TEncoding, TEncodedSolution> original, Cloner cloner)
       : base(original, cloner) {
+      MaximizationParameter = cloner.Clone(original.MaximizationParameter);
       ParameterizeOperators();
     }
 
     protected MultiObjectiveProblem() : base() {
-      Parameters.Add(new ValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()));
+      MaximizationParameter = new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", new BoolArray(new[] { false, false }).AsReadOnly()) { Hidden = true, ReadOnly = true };
+      Parameters.Add(MaximizationParameter);
       Parameters.Add(new OptionalValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion."));
       Parameters.Add(new OptionalValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem"));
@@ -73,5 +72,6 @@
 
     protected MultiObjectiveProblem(TEncoding encoding) : base(encoding) {
-      Parameters.Add(new ValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()));
+      MaximizationParameter = new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", new BoolArray(new[] { false, false }).AsReadOnly()) { Hidden = true, ReadOnly = true };
+      Parameters.Add(MaximizationParameter);
       Parameters.Add(new OptionalValueParameter<DoubleMatrix>(BestKnownFrontParameterName, "A double matrix representing the best known qualites for this problem (aka points on the Pareto front). Points are to be given in a row-wise fashion."));
       Parameters.Add(new OptionalValueParameter<DoubleArray>(ReferencePointParameterName, "The refrence point for hypervolume calculations on this problem"));
@@ -89,5 +89,16 @@
       get { return Maximization.Length; }
     }
-    public abstract bool[] Maximization { get; }
+    IReadOnlyList<bool> IMultiObjectiveProblemDefinition.Maximization {
+      get { return Maximization.CloneAsArray(); }
+    }
+    public BoolArray Maximization {
+      get { return MaximizationParameter.Value; }
+      set {
+        if (Maximization == value) return;
+        MaximizationParameter.ReadOnly = false;
+        MaximizationParameter.Value = value.AsReadOnly();
+        MaximizationParameter.ReadOnly = true;
+      }
+    }
 
     public virtual IReadOnlyList<double[]> BestKnownFront {
@@ -168,5 +179,5 @@
     #region IMultiObjectiveHeuristicOptimizationProblem Members
     IParameter IMultiObjectiveHeuristicOptimizationProblem.MaximizationParameter {
-      get { return Parameters[MaximizationParameterName]; }
+      get { return MaximizationParameter; }
     }
     IMultiObjectiveEvaluator IMultiObjectiveHeuristicOptimizationProblem.Evaluator {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/DominationCalculator.cs	(revision 17309)
@@ -47,5 +47,5 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>The pareto front containing the best solutions and their associated quality resp. fitness.</returns>
-    public static List<Tuple<T, double[]>> CalculateBestParetoFront<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities = true) {
+    public static List<Tuple<T, double[]>> CalculateBestParetoFront<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, bool dominateOnEqualQualities = true) {
       var populationSize = solutions.Length;
       Dictionary<T, List<int>> dominatedIndividuals;
@@ -72,5 +72,5 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>A sorted list of the pareto fronts from best to worst.</returns>
-    public static List<List<Tuple<T, double[]>>> CalculateAllParetoFronts<T>(T[] solutions, double[][] qualities, bool[] maximization, out int[] rank, bool dominateOnEqualQualities = true) {
+    public static List<List<Tuple<T, double[]>>> CalculateAllParetoFronts<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, out int[] rank, bool dominateOnEqualQualities = true) {
       var populationSize = solutions.Length;
 
@@ -101,5 +101,5 @@
     }
 
-    private static List<Tuple<T, double[]>> CalculateBestFront<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities, int populationSize, out Dictionary<T, List<int>> dominatedIndividuals, out int[] dominationCounter, out int[] rank) {
+    private static List<Tuple<T, double[]>> CalculateBestFront<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, bool dominateOnEqualQualities, int populationSize, out Dictionary<T, List<int>> dominatedIndividuals, out int[] dominationCounter, out int[] rank) {
       var front = new List<Tuple<T, double[]>>();
       dominatedIndividuals = new Dictionary<T, List<int>>();
@@ -155,5 +155,5 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>A sorted list of the pareto fronts where each front contains the indices of the <paramref name="solutions"/> and <paramref name="qualities"/>.</returns>
-    public static List<List<int>> CalculateAllParetoFrontsIndices<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities = true) {
+    public static List<List<int>> CalculateAllParetoFrontsIndices<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, bool dominateOnEqualQualities = true) {
       return CalculateAllParetoFrontsIndices(solutions, qualities, maximization, out var rank, dominateOnEqualQualities);
     }
@@ -178,5 +178,5 @@
     /// <param name="dominateOnEqualQualities">Whether solutions of exactly equal quality should dominate one another.</param>
     /// <returns>A sorted list of the pareto fronts where each front contains the indices of the <paramref name="solutions"/> and <paramref name="qualities"/>.</returns>
-    public static List<List<int>> CalculateAllParetoFrontsIndices<T>(T[] solutions, double[][] qualities, bool[] maximization, out int[] rank, bool dominateOnEqualQualities = true) {
+    public static List<List<int>> CalculateAllParetoFrontsIndices<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, out int[] rank, bool dominateOnEqualQualities = true) {
       var populationSize = solutions.Length;
 
@@ -207,5 +207,5 @@
     }
 
-    private static List<int> CalculateBestFrontIndices<T>(T[] solutions, double[][] qualities, bool[] maximization, bool dominateOnEqualQualities, int populationSize, List<int>[] dominatedIndividuals, int[] dominationCounter, int[] rank) {
+    private static List<int> CalculateBestFrontIndices<T>(T[] solutions, double[][] qualities, IReadOnlyList<bool> maximization, bool dominateOnEqualQualities, int populationSize, List<int>[] dominatedIndividuals, int[] dominationCounter, int[] rank) {
       var front = new List<int>();
       for (var pI = 0; pI < populationSize - 1; pI++) {
@@ -244,5 +244,5 @@
     /// <param name="dominateOnEqualQualities">Whether the result should be Dominates in case both fitness vectors are exactly equal</param>
     /// <returns>Dominates if left dominates right, IsDominated if right dominates left and IsNonDominated otherwise.</returns>
-    public static DominationResult Dominates(double[] left, double[] right, bool[] maximizations, bool dominateOnEqualQualities) {
+    public static DominationResult Dominates(double[] left, double[] right, IReadOnlyList<bool> maximizations, bool dominateOnEqualQualities) {
       //mkommend Caution: do not use LINQ.SequenceEqual for comparing the two quality arrays (left and right) due to performance reasons
       if (dominateOnEqualQualities) {
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Optimization/3.3/MultiObjective/HypervolumeCalculator.cs	(revision 17309)
@@ -26,5 +26,5 @@
 namespace HeuristicLab.Optimization {
   public static class HypervolumeCalculator {
-    public static double[] CalculateNadirPoint(IEnumerable<double[]> qualities, bool[] maximization) {
+    public static double[] CalculateNadirPoint(IEnumerable<double[]> qualities, IReadOnlyList<bool> maximization) {
       var res = maximization.Select(m => m ? double.MaxValue : double.MinValue).ToArray();
       foreach (var quality in qualities)
@@ -59,11 +59,11 @@
     /// </summary>
     /// 
-    public static double CalculateHypervolume(IList<double[]> qualities, double[] referencePoint, bool[] maximization) {
+    public static double CalculateHypervolume(IList<double[]> qualities, double[] referencePoint, IReadOnlyList<bool> maximization) {
       qualities = qualities.Where(vec => DominationCalculator.Dominates(vec, referencePoint, maximization, false) == DominationResult.Dominates).ToArray();
       if (qualities.Count== 0) return 0; //TODO computation for negative hypervolume?
-      if (maximization.Length == 2)
+      if (maximization.Count == 2)
         return Calculate2D(qualities, referencePoint, maximization);
 
-      if (Array.TrueForAll(maximization, x => !x))
+      if (maximization.All(x => !x))
         return CalculateMultiDimensional(qualities, referencePoint);
       throw new NotImplementedException("HypervolumeCalculator calculation for more than two dimensions is supported only with minimization problems.");
@@ -78,5 +78,5 @@
     /// <param name="maximization"></param>
     /// <returns></returns>
-    public static double Calculate2D(IList<double[]> front, double[] referencePoint, bool[] maximization) {
+    public static double Calculate2D(IList<double[]> front, double[] referencePoint, IReadOnlyList<bool> maximization) {
       if (front == null) throw new ArgumentNullException("front");
       if (referencePoint == null) throw new ArgumentNullException("referencePoint");
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.ExternalEvaluation/3.4/MultiObjectiveExternalEvaluationProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.ExternalEvaluation/3.4/MultiObjectiveExternalEvaluationProblem.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.ExternalEvaluation/3.4/MultiObjectiveExternalEvaluationProblem.cs	(revision 17309)
@@ -90,6 +90,6 @@
     public MultiObjectiveExternalEvaluationProblem(TEncoding encoding)
       : base(encoding) {
-      Parameters.Remove("Maximization"); // readonly in base class
-      Parameters.Add(new FixedValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", new BoolArray()));
+      MaximizationParameter.ReadOnly = false;
+      MaximizationParameter.Value = new BoolArray(new [] { false, false });
       Parameters.Add(new OptionalValueParameter<EvaluationCache>("Cache", "Cache of previously evaluated solutions."));
       Parameters.Add(new ValueParameter<CheckedItemCollection<IEvaluationServiceClient>>("Clients", "The clients that are used to communicate with the external application.", new CheckedItemCollection<IEvaluationServiceClient>() { new EvaluationServiceClient() }));
@@ -99,10 +99,4 @@
 
     #region Multi Objective Problem Overrides
-    public override bool[] Maximization {
-      get {
-        return Parameters.ContainsKey("Maximization") ? ((IValueParameter<BoolArray>)Parameters["Maximization"]).Value.ToArray() : new bool[0];
-      }
-    }
-
     public virtual void SetMaximization(bool[] maximization) {
       ((IStringConvertibleArray)MaximizationParameter.Value).Length = maximization.Length;
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/CompiledProblemDefinition.cs	(revision 17309)
@@ -23,5 +23,4 @@
 using System.Collections.Generic;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 
@@ -78,6 +77,6 @@
 
     #region ISingleObjectiveProblemDefinition<TEncoding,TEncodedSolution> Members
-    public int Objectives => Maximization.Length;
-    public abstract bool[] Maximization { get; }
+    public int Objectives => Maximization.Count;
+    public abstract IReadOnlyList<bool> Maximization { get; }
     public abstract IReadOnlyList<double[]> BestKnownFront { get; }
     public abstract double[] ReferencePoint { get; }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProblemDefinitionScript.cs	(revision 17309)
@@ -24,5 +24,4 @@
 using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
 using HeuristicLab.Optimization;
 
@@ -52,5 +51,5 @@
     public IReadOnlyList<double[]> BestKnownFront => CompiledProblemDefinition.BestKnownFront;
     public double[] ReferencePoint => CompiledProblemDefinition.ReferencePoint;
-    public bool[] Maximization => CompiledProblemDefinition.Maximization;
+    public IReadOnlyList<bool> Maximization => CompiledProblemDefinition.Maximization;
 
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/MultiObjectiveProgrammableProblem.cs	(revision 17309)
@@ -94,6 +94,5 @@
 
     private void OnProblemDefinitionChanged() {
-      Parameters.Remove("Maximization");
-      Parameters.Add(new ValueParameter<BoolArray>("Maximization", "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(Maximization).AsReadOnly()) {Hidden = true});
+      Maximization = new BoolArray(ProblemDefinition.Maximization);
       Encoding = (TEncoding)ProblemScript.Encoding.Clone();
 
@@ -107,8 +106,4 @@
     private void OnProblemScriptNameChanged() {
       Name = ProblemScript.Name;
-    }
-
-    public override bool[] Maximization {
-      get { return Parameters.ContainsKey("ProblemScript") ? ProblemDefinition.Maximization : new[] {false}; }
     }
 
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.Programmable/3.3/Templates/MultiObjectiveCombinedEncodingProblem_Template.cs	(revision 17309)
@@ -16,5 +16,5 @@
 namespace HeuristicLab.Problems.Programmable {
   public class CompiledMultiObjectiveProblemDefinition : CompiledMultiObjectiveProblemDefinition<CombinedEncoding, CombinedSolution> {
-    public override bool[] Maximization { get { return new[] { true, false }; } }
+    public override IReadOnlyList<bool> Maximization { get { return new[] { true, false }; } }
     public override double[] ReferencePoint { get { return null; } }
     public override IReadOnlyList<double[]> BestKnownFront { get { return null; } }
Index: /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs
===================================================================
--- /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 17308)
+++ /branches/2521_ProblemRefactoring/HeuristicLab.Problems.TestFunctions.MultiObjective/3.3/MultiObjectiveTestFunctionProblem.cs	(revision 17309)
@@ -20,5 +20,4 @@
 #endregion
 using System;
-using System.Linq;
 using HEAL.Attic;
 using HeuristicLab.Analysis;
@@ -52,12 +51,4 @@
 
     #region Properties
-    public override bool[] Maximization {
-      get {
-        //necessary because of virtual member call in base ctor
-        if (!Parameters.ContainsKey("TestFunction")) return new bool[0];
-        return TestFunction.Maximization(Objectives).ToArray();
-      }
-    }
-
     public int ProblemSize {
       get { return ProblemSizeParameter.Value.Value; }
@@ -141,6 +132,5 @@
     #region Events
     private void UpdateParameterValues() {
-      Parameters.Remove(MaximizationParameterName);
-      Parameters.Add(new FixedValueParameter<BoolArray>(MaximizationParameterName, "Set to false if the problem should be minimized.", (BoolArray)new BoolArray(TestFunction.Maximization(Objectives)).AsReadOnly()));
+      Maximization = new BoolArray(TestFunction.Maximization(Objectives));
 
       Parameters.Remove(BestKnownFrontParameterName);
