Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs	(revision 6489)
@@ -75,8 +75,8 @@
         bestSolutionHistory = results[key].Value as RunCollection;
       }
-      if (bestSolutionHistory.Count == 0 || best.ParameterInfoString != ((StringValue)bestSolutionHistory.Last().Results["Meta.ParameterInfoString"]).Value) {
+      if (bestSolutionHistory.Count == 0 || best.ParameterInfoString != ((StringValue)bestSolutionHistory.Last().Results["Meta-ParameterInfoString"]).Value) {
         IRun run = best.ToRun(string.Format("{0}: {1}", currentGeneration, best.ParameterInfoString), false);
-        run.Results.Add("Meta.Generation", new IntValue(currentGeneration));
-        run.Results.Add("Meta.ParameterInfoString", new StringValue(best.ParameterInfoString));
+        run.Results.Add("Meta-Generation", new IntValue(currentGeneration));
+        run.Results.Add("Meta-ParameterInfoString", new StringValue(best.ParameterInfoString));
         bestSolutionHistory.Add(run);
       }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/SolutionCacheAnalyzer.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/SolutionCacheAnalyzer.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/SolutionCacheAnalyzer.cs	(revision 6489)
@@ -74,6 +74,6 @@
           var runCollection = allRuns.Single(x => x.Key.Value == key).Value;
           foreach (var run in solution.Runs) {
-            if (!((BoolValue)run.Results["Meta.FromCache"]).Value || first) {
-              run.Results["Meta.FromCache"] = new BoolValue(true);
+            if (!((BoolValue)run.Results["Meta-FromCache"]).Value || first) {
+              run.Results["Meta-FromCache"] = new BoolValue(true);
               runCollection.Add(run);
             }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 6489)
@@ -22,5 +22,5 @@
       get {
         if (!initialized)
-          throw new SystemException("Enumeration not started. Call MoveNext!");
+          throw new InvalidOperationException("Enumeration not started. Call MoveNext!");
         return Current;
       }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 6489)
@@ -161,4 +161,8 @@
       this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Algorithm", algproblemitem.AlgorithmParameter));
       this.parameterConfigurations.Add(new SingleValuedParameterConfiguration("Problem", algproblemitem.ProblemParameter));
+
+      // problems can be modified in the list of problem instances, so the parameters which are not Optimize=true, 
+      // must not be modifiable in the parameter configuration tree. otherwise the parameter values would be ambiguous
+      ProblemConfiguration.ValuesReadOnly = true;
     }
     public ParameterConfigurationTree() { }
@@ -190,4 +194,5 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserialization() {
+      if(ProblemConfiguration != null) ProblemConfiguration.ValuesReadOnly = true;
     }
     #endregion
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs	(revision 6489)
@@ -146,4 +146,17 @@
     }
 
+    [Storable]
+    protected bool valuesReadOnly = false;
+    public virtual bool ValuesReadOnly {
+      get { return valuesReadOnly; }
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+          foreach (var vc in this.valueConfigurations) {
+            vc.ValuesReadOnly = value;
+          }
+        }
+      }
+    }
 
     #region Constructors and Cloning
@@ -220,4 +233,5 @@
       this.discoverValidValues = original.discoverValidValues;
       this.AutoPopulateValueConfigurations = original.AutoPopulateValueConfigurations;
+      this.valuesReadOnly = original.valuesReadOnly;
     }
 
@@ -485,4 +499,7 @@
 
     public void Parameterize(IValueParameter parameter) {
+      if (!Optimize && ValuesReadOnly)
+        return;
+
       if (Optimize) {
         if (this.ActualValue.Value is IParameterizedItem) {
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 6489)
@@ -46,4 +46,15 @@
       get { return discoverValidValues; }
       set { discoverValidValues = value; }
+    }
+
+    public override bool ValuesReadOnly {
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+          foreach (var pc in this.parameterConfigurations) {
+            pc.ValuesReadOnly = value;
+          }
+        }
+      }
     }
 
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 6489)
@@ -73,4 +73,15 @@
     }
 
+    [Storable]
+    protected bool valuesReadOnly = false;
+    public virtual bool ValuesReadOnly {
+      get { return valuesReadOnly; }
+      set {
+        if (value != this.valuesReadOnly) {
+          this.valuesReadOnly = value;
+        }
+      }
+    }
+
     #region Constructors and Cloning
     public ValueConfiguration(IItem value, Type valueDataType) {
@@ -88,4 +99,5 @@
       this.optimize = original.optimize;
       this.number = original.number;
+      this.valuesReadOnly = original.valuesReadOnly;
       RegisterActualValueEvents();
     }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs	(revision 6489)
@@ -69,4 +69,7 @@
     public IScope CurrentScope {
       get { return CurrentScopeParameter.ActualValue; }
+    }
+    public LookupParameter<StringValue> QualityMeasureNameParameter {
+      get { return (LookupParameter<StringValue>)Parameters[MetaOptimizationProblem.QualityMeasureNameName]; }
     }
     #endregion
@@ -93,4 +96,5 @@
       Parameters.Add(new LookupParameter<DoubleValue>(MetaOptimizationProblem.StandardDeviationWeightParameterName));
       Parameters.Add(new LookupParameter<DoubleValue>(MetaOptimizationProblem.EvaluatedSolutionsWeightParameterName));
+      Parameters.Add(new LookupParameter<StringValue>(MetaOptimizationProblem.QualityMeasureNameName));
       Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents."));
     }
@@ -104,4 +108,5 @@
     private void AfterDeserialization() {
       if (!Parameters.ContainsKey("CurrentScope")) Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents.")); // backwards compatibility
+      if (!Parameters.ContainsKey(MetaOptimizationProblem.QualityMeasureNameName)) Parameters.Add(new LookupParameter<StringValue>(MetaOptimizationProblem.QualityMeasureNameName)); // backwards compatibility
     }
 
@@ -118,5 +123,6 @@
       double standardDeviationWeight = StandardDeviationWeightParameter.ActualValue.Value;
       double evaluatedSolutionsWeight = EvaluatedSolutionsWeightParameter.ActualValue.Value;
-      var resultNames = new List<string> { "BestQuality", "Execution Time", "EvaluatedSolutions" };
+      string qualityMeasureName = QualityMeasureNameParameter.ActualValue.Value;
+      var resultNames = new List<string> { qualityMeasureName, "Execution Time", "EvaluatedSolutions" };
       int currentGeneration = GenerationsParameter.ActualValue != null ? GenerationsParameter.ActualValue.Value : 0;
       double[] referenceQualityAverages;
@@ -146,9 +152,10 @@
           MetaOptimizationUtil.ClearResults(run, resultNames);
           MetaOptimizationUtil.ClearParameters(run, parameterNames);
-          run.Results.Add("Meta.FromCache", new BoolValue(false));
-          run.Results.Add("Meta.Generation", new IntValue(currentGeneration));
-          run.Results.Add("Meta.ProblemIndex", new IntValue(problemIndex));
+          run.Results.Add("Meta-FromCache", new BoolValue(false));
+          run.Results.Add("Meta-Generation", new IntValue(currentGeneration));
+          run.Results.Add("Meta-ProblemIndex", new IntValue(problemIndex));
           run.Name = string.Format("{0} Problem {1} Run {2}", parameterConfiguration.ParameterInfoString, problemIndex, repetitionIndex);
-          qualities[problemIndex][repetitionIndex] = (((DoubleValue)run.Results["BestQuality"]).Value);
+          
+          qualities[problemIndex][repetitionIndex] = GetResultValue<DoubleValue>(run.Results, qualityMeasureName).Value; 
           executionTimes[problemIndex][repetitionIndex] = (((TimeSpanValue)run.Results["Execution Time"]).Value);
           evaluatedSolutions[problemIndex][repetitionIndex] = (((IntValue)run.Results["EvaluatedSolutions"]).Value);
@@ -203,4 +210,25 @@
       
       return base.Apply();
+    }
+
+    private T1 GetResultValue<T1>(IDictionary<string, IItem> results, string resultName) {
+      return (T1)results[resultName];
+
+      //string separator = ".";
+      //string[] tokens = resultName.Split(separator.ToCharArray());
+
+      //IDictionary<string, IItem> currentResults = results;
+      //IItem currentResult = null;
+      //for (int i = 0; i < tokens.Length; i++) {
+      //  if(currentResults == null)
+      //    throw new KeyNotFoundException("Result value " + resultName + " was not found");
+      //  if (currentResults.ContainsKey(tokens[i])) {
+      //    currentResult = currentResults[tokens[i]];
+      //    currentResults = currentResult as IDictionary<string, IItem>;
+      //  } else {
+      //    throw new KeyNotFoundException("Result value " + resultName + " was not found");
+      //  }
+      //}
+      //return (T1)currentResult;
     }
 
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs	(revision 6489)
@@ -26,4 +26,9 @@
     event EventHandler IsOptimizableChanged;
     event EventHandler OptimizeChanged;
+
+    /// <summary>
+    /// indicates if the actualvalues are modifiable
+    /// </summary>
+    bool ValuesReadOnly { get; set; }
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 6486)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 6489)
@@ -40,5 +40,5 @@
   public sealed class MetaOptimizationProblem : SingleObjectiveHeuristicOptimizationProblem<IParameterConfigurationEvaluator, IParameterConfigurationCreator>, IStorableContent {
     public string Filename { get; set; }
-    
+
     public const string AlgorithmTypeParameterName = "AlgorithmType";
     public const string ProblemTypeParameterName = "ProblemType";
@@ -46,4 +46,5 @@
     public const string ParameterConfigurationTreeParameterName = "ParameterConfiguration";
     public const string RepetitionsParameterName = "Repetitions";
+    public const string QualityMeasureNameName = "QualityMeasureName";
 
     public const string IntValueManipulatorParameterName = "IntValueManipulator";
@@ -67,5 +68,5 @@
     }
     public IValueParameter<ParameterConfigurationTree> ParameterConfigurationTreeParameter {
-      get { return (ValueParameter<ParameterConfigurationTree>)Parameters[ParameterConfigurationTreeParameterName]; }
+      get { return (OptionalValueParameter<ParameterConfigurationTree>)Parameters[ParameterConfigurationTreeParameterName]; }
     }
     public IValueParameter<IntValue> RepetitionsParameter {
@@ -79,4 +80,7 @@
     public IValueParameter<IDoubleValueManipulator> DoubleValueManipulatorParameter {
       get { return (ValueParameter<IDoubleValueManipulator>)Parameters[DoubleValueManipulatorParameterName]; }
+    }
+    public IValueParameter<StringValue> QualityMeasureNameParameter {
+      get { return (ValueParameter<StringValue>)Parameters[QualityMeasureNameName]; }
     }
     #endregion
@@ -131,6 +135,7 @@
       Parameters.Add(new ValueParameter<ConstrainedTypeValue<IProblem>>(ProblemTypeParameterName, "The problem type.", new ConstrainedTypeValue<IProblem>()));
       Parameters.Add(new ValueParameter<ConstrainedItemList<IProblem>>(ProblemsParameterName, "The problems that should be evaluated.", new ConstrainedItemList<IProblem>()));
-      Parameters.Add(new ValueParameter<ParameterConfigurationTree>(ParameterConfigurationTreeParameterName, "Tree of algorithm parameters that should be optimized."));
+      Parameters.Add(new OptionalValueParameter<ParameterConfigurationTree>(ParameterConfigurationTreeParameterName, "Tree of algorithm parameters that should be optimized.")); // needs to be optional, when last problem is removed from list, it must be set null
       Parameters.Add(new ValueParameter<IntValue>(RepetitionsParameterName, "The number of evaluations for each problem.", new IntValue(3)));
+      Parameters.Add(new ValueParameter<StringValue>(QualityMeasureNameName, "The name of the quality result of the base-level algorithm. Subresults can be accessed by dot separator.", new StringValue("BestQuality")));
 
       var validIntManipulators = new ItemSet<IIntValueManipulator>(ApplicationManager.Manager.GetInstances<IIntValueManipulator>());
@@ -174,4 +179,5 @@
     [StorableHook(HookType.AfterDeserialization)]
     private void AfterDeserializationHook() {
+      if(!Parameters.ContainsKey(QualityMeasureNameName)) Parameters.Add(new ValueParameter<StringValue>(QualityMeasureNameName, "The name of the quality result of the base-level algorithm. Subresults can be accessed by dot separator.", new StringValue("BestQuality"))); // backwards compatibility
       RegisterParameterEvents();
     }
@@ -211,5 +217,5 @@
       if (RunsAnalyzer != null) {
         RunsAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
-      } 
+      }
       if (PMOPopulationDiversityAnalyzer != null) {
         PMOPopulationDiversityAnalyzer.SolutionParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
@@ -260,6 +266,9 @@
       IAlgorithm instance = (IAlgorithm)Activator.CreateInstance(AlgorithmType.Value);
       this.ProblemType.ValidTypes = ApplicationManager.Manager.GetTypes(instance.ProblemType, true).ToList();
-      this.ProblemType.Value = this.ProblemType.ValidTypes.SingleOrDefault(t => t == typeof(SingleObjectiveTestFunctionProblem)) ?? this.ProblemType.ValidTypes.Where(t => t != typeof(MetaOptimizationProblem)).FirstOrDefault();
-      // ProblemType_ValueChanged will add one problem and create ParameterConfigurationTree
+      var newProblemType = this.ProblemType.ValidTypes.SingleOrDefault(t => t == typeof(SingleObjectiveTestFunctionProblem)) ?? this.ProblemType.ValidTypes.Where(t => t != typeof(MetaOptimizationProblem)).FirstOrDefault();
+      if (this.ProblemType.Value != newProblemType)
+        this.ProblemType.Value = newProblemType; // ProblemType_ValueChanged will add one problem and create ParameterConfigurationTree
+      else
+        ProblemType_ValueChanged(this, EventArgs.Empty); // call explicitly
     }
 
@@ -274,5 +283,5 @@
     }
 
-    private void Problems_ItemsAdded(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IProblem>> e) {
+    private void Problems_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IProblem>> e) {
       // the first problem in the list is always the instance for the algorithm - this way some basic wiring between problem and algorithm can be sustained
       if (e.Items.Single().Index == 0) {
@@ -287,5 +296,5 @@
     }
 
-    private void Problems_ItemsRemoved(object sender, Collections.CollectionItemsChangedEventArgs<IndexedItem<IProblem>> e) {
+    private void Problems_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IProblem>> e) {
       if (e.Items.Single().Index == 0) {
         ParameterConfigurationTreeParameter.ActualValue = null;
