Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs	(revision 5653)
@@ -2,8 +2,11 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.IO;
 using System.Linq;
+using System.Reflection;
 using System.Text;
 using System.Threading;
+using System.Threading.Tasks;
 using HeuristicLab.Algorithms.EvolutionStrategy;
 using HeuristicLab.Algorithms.GeneticAlgorithm;
@@ -11,18 +14,13 @@
 using HeuristicLab.Core;
 using HeuristicLab.Data;
+using HeuristicLab.Hive.ExperimentManager;
 using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
 using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.PluginInfrastructure.Manager;
 using HeuristicLab.Problems.MetaOptimization;
 using HeuristicLab.Problems.TestFunctions;
 using HeuristicLab.Random;
 using HeuristicLab.Selection;
-using HeuristicLab.Parameters;
-using HeuristicLab.Operators;
-using System.Diagnostics;
-using HeuristicLab.Encodings.RealVectorEncoding;
-using HeuristicLab.Hive.ExperimentManager;
-using System.Threading.Tasks;
-using HeuristicLab.PluginInfrastructure.Manager;
-using System.Reflection;
 
 namespace HeuristicLab.MetaOptimization.Test {
@@ -70,5 +68,5 @@
       //TestEnumeratorCollectionEnumerator();
       //TestCombinations4(); return;
-      //TestAlgorithmPerformanceIssue();
+      //TestAlgorithmPerformanceIssue(); return;
       //TestWaitAny();
       //TestExecutionTimeUpdateInvervalPerformance();
@@ -76,7 +74,5 @@
       //TestNormalCrossover();
       //TestItemDictionary();
-
-
-
+      
       MetaOptimizationProblem metaOptimizationProblem = new MetaOptimizationProblem();
       metaOptimizationProblem.Repetitions = new IntValue(metaProblemRepetitions);
@@ -87,5 +83,5 @@
       //EvolutionStrategy metaLevelAlgorithm = GetMetaES(metaOptimizationProblem);
 
-      IValueConfiguration algorithmVc = SetupGAAlgorithm(typeof(GeneticAlgorithm), metaOptimizationProblem);
+      var algorithmVc = SetupGAAlgorithm(typeof(GeneticAlgorithm), metaOptimizationProblem);
 
       //TestToString(algorithmVc);
@@ -94,5 +90,5 @@
       //Console.WriteLine("Press enter to start");
       //Console.ReadLine();
-      //TestConfiguration(algorithmVc, baseLevelAlgorithm);
+      //TestConfiguration(algorithmVc, new GeneticAlgorithm());
 
       //Console.WriteLine("Press enter to start");
@@ -140,5 +136,5 @@
       vc1.ParameterConfigurations.Single(x => x.Name == "Selector").Optimize = true;
 
-      var vc2 = (IValueConfiguration)vc1.Clone();
+      var vc2 = (ParameterConfigurationTree)vc1.Clone();
       Console.WriteLine("Assert(1): {0}", vc1.CalculateSimilarity(vc2));
 
@@ -289,6 +285,5 @@
           swx.Start();
           ((EngineAlgorithm)alg).ExecutionTimeChanged += new EventHandler(Program_ExecutionTimeChanged);
-          var executor = new AlgorithmExecutor((EngineAlgorithm)alg);
-          executor.StartSync();
+          ((EngineAlgorithm)alg).StartSync();
           ((EngineAlgorithm)alg).ExecutionTimeChanged -= new EventHandler(Program_ExecutionTimeChanged);
           swx.Stop();
@@ -369,4 +364,5 @@
       Queue<TimeSpan> latestExecutionTimes = new Queue<TimeSpan>();
       int size = 10;
+      var random = new Random.MersenneTwister(0);
 
       GeneticAlgorithm ga = new GeneticAlgorithm();
@@ -374,20 +370,32 @@
       ga.MaximumGenerations.Value = 1;
       ga.Engine = new SequentialEngine.SequentialEngine();
-      throw new NotImplementedException("TODO: Set ga parameters correctly");
+      ga.Problem = new SingleObjectiveTestFunctionProblem();
 
       MetaOptimizationProblem metaOptimizationProblem = new MetaOptimizationProblem();
-      metaOptimizationProblem.Repetitions = new IntValue(metaProblemRepetitions);
+      //metaOptimizationProblem.Repetitions = new IntValue(metaProblemRepetitions);
       GeneticAlgorithm metaLevelAlgorithm = GetMetaGA(metaOptimizationProblem);
       ParameterConfigurationTree algorithmVc = SetupGAAlgorithm(typeof(GeneticAlgorithm), metaOptimizationProblem);
+      algorithmVc.Randomize(random);
       Stopwatch sw = new Stopwatch();
 
+      var algs = new Queue<IAlgorithm>(); // keep them in memory 
+      // -> BINGO! -> .NET cannot hold more than 16 algorithms with their ThreadLocal<T> objects efficiently, 
+      // so if they are kept in memory, runtime at the 17. execution drops significantly
+      // because creating ThreadLocal<T> takes all the runtime.
+      // when the algs are not stored in a list however this effect does not occur.
+      
+
       for (int i = 0; i < 1000; i++) {
-        sw.Start();
         GeneticAlgorithm clonedGa = (GeneticAlgorithm)ga.Clone();
         clonedGa.Name = "CLONED GA";
-        algorithmVc.Parameterize(clonedGa);
+        //algorithmVc.Randomize(random);
+        //algorithmVc.Parameterize(clonedGa);
         clonedGa.Prepare(true);
-        var executor = new AlgorithmExecutor(clonedGa);
-        executor.StartSync();
+        sw.Start();
+        algs.Enqueue(clonedGa);
+
+        if (algs.Count > 24)
+          algs.Dequeue();
+        clonedGa.StartSync();
         sw.Stop();
         latestExecutionTimes.Enqueue(sw.Elapsed);
@@ -549,5 +557,5 @@
     private static void TestTypeDiscovery() {
       PluginLoader.pluginAssemblies.Any();
-
+      
       var items = ApplicationManager.Manager.GetInstances(typeof(DoubleArray)).ToArray();
 
@@ -634,30 +642,31 @@
       ((IntValue)algorithmVc.ParameterConfigurations.Single(x => x.Name == "MaximumGenerations").ActualValue.Value).Value = baseAlgorithmMaxGenerations;
 
+      metaOptimizationProblem.Problems.Clear();
       metaOptimizationProblem.Problems.Add(new HeuristicLab.Problems.TestFunctions.SingleObjectiveTestFunctionProblem() {
         Evaluator = new GriewankEvaluator(),
         ProblemSize = new IntValue(2)
       });
-      metaOptimizationProblem.Problems.Add(new HeuristicLab.Problems.TestFunctions.SingleObjectiveTestFunctionProblem() {
-        Evaluator = new GriewankEvaluator(),
-        ProblemSize = new IntValue(20)
-      });
-      metaOptimizationProblem.Problems.Add(new HeuristicLab.Problems.TestFunctions.SingleObjectiveTestFunctionProblem() {
-        Evaluator = new GriewankEvaluator(),
-        ProblemSize = new IntValue(500)
-      });
-
-      ConfigurePopulationSize(algorithmVc, 5, 20, 1);
-      ConfigureMutationRate(algorithmVc, 0.0, 1.0, 0.01);
+      //metaOptimizationProblem.Problems.Add(new HeuristicLab.Problems.TestFunctions.SingleObjectiveTestFunctionProblem() {
+      //  Evaluator = new GriewankEvaluator(),
+      //  ProblemSize = new IntValue(20)
+      //});
+      //metaOptimizationProblem.Problems.Add(new HeuristicLab.Problems.TestFunctions.SingleObjectiveTestFunctionProblem() {
+      //  Evaluator = new GriewankEvaluator(),
+      //  ProblemSize = new IntValue(500)
+      //});
+
+      //ConfigurePopulationSize(algorithmVc, 15, 20, 1);
+      //ConfigureMutationRate(algorithmVc, 0.0, 1.0, 0.01);
       ConfigureMutationOperator(algorithmVc);
-      //ConfigureElites(algorithmVc, 0, 30, 1);
-      ConfigureSelectionOperator(algorithmVc, true);
+      //ConfigureElites(algorithmVc, 0, 8, 1);
+      //ConfigureSelectionOperator(algorithmVc, true);
       return algorithmVc;
     }
 
-    private static void TestConfiguration(IValueConfiguration algorithmVc, GeneticAlgorithm baseLevelAlgorithm) {
+    private static void TestConfiguration(ParameterConfigurationTree algorithmVc, GeneticAlgorithm baseLevelAlgorithm) {
       IRandom rand = new FastRandom(0);
       // set random values
       for (int i = 0; i < 10; i++) {
-        IValueConfiguration clonedVc = (IValueConfiguration)algorithmVc.Clone();
+        var clonedVc = (ParameterConfigurationTree)algorithmVc.Clone();
         GeneticAlgorithm newAlg = (GeneticAlgorithm)baseLevelAlgorithm.Clone();
         clonedVc.Randomize(rand);
@@ -676,5 +685,5 @@
       // mutate
       for (int i = 0; i < 10; i++) {
-        IValueConfiguration clonedVc = (IValueConfiguration)algorithmVc.Clone();
+        var clonedVc = (ParameterConfigurationTree)algorithmVc.Clone();
         GeneticAlgorithm newAlg = (GeneticAlgorithm)baseLevelAlgorithm.Clone();
         ParameterConfigurationManipulator.Apply(rand, clonedVc, new UniformIntValueManipulator(), new NormalDoubleValueManipulator());
@@ -692,6 +701,6 @@
       // cross
       for (int i = 0; i < 10; i++) {
-        IValueConfiguration clonedVc1 = (IValueConfiguration)algorithmVc.Clone();
-        IValueConfiguration clonedVc2 = (IValueConfiguration)algorithmVc.Clone();
+        var clonedVc1 = (ParameterConfigurationTree)algorithmVc.Clone();
+        var clonedVc2 = (ParameterConfigurationTree)algorithmVc.Clone();
 
         GeneticAlgorithm first = (GeneticAlgorithm)baseLevelAlgorithm.Clone();
@@ -725,5 +734,5 @@
     }
 
-    private static void ConfigureMutationOperator(IValueConfiguration algorithmVc) {
+    private static void ConfigureMutationOperator(ParameterConfigurationTree algorithmVc) {
       var mutationOperator = algorithmVc.ParameterConfigurations.Where(x => x.Name == "Mutator").SingleOrDefault();
       mutationOperator.Optimize = true;
@@ -735,9 +744,9 @@
       }
 
-      // add another normal
-      mutationOperator.ValueConfigurations.Add(new ValueConfiguration(new NormalAllPositionsManipulator(), typeof(NormalAllPositionsManipulator)), true);
-    }
-
-    private static void ConfigureSelectionOperator(IValueConfiguration algorithmVc, bool configureTournamenSize) {
+      // add another normal - don't do this with 'new', because ActualNames will not be set correctly. It should be copied from an existing one
+      // mutationOperator.ValueConfigurations.Add(new ParameterizedValueConfiguration(new NormalAllPositionsManipulator(), typeof(NormalAllPositionsManipulator)), true);
+    }
+
+    private static void ConfigureSelectionOperator(ParameterConfigurationTree algorithmVc, bool configureTournamenSize) {
       var selectionOperatorPc = algorithmVc.ParameterConfigurations.Where(x => x.Name == "Selector").SingleOrDefault();
       selectionOperatorPc.Optimize = true;
@@ -748,5 +757,5 @@
           if (configureTournamenSize) {
             vc.Optimize = true;
-            ConfigureTournamentGroupSize(vc);
+            ConfigureTournamentGroupSize((ParameterizedValueConfiguration)vc);
           }
         } else if (vc.ActualValue.ValueDataType == typeof(RandomSelector)) {
@@ -758,18 +767,18 @@
     }
 
-    private static void ConfigureTournamentGroupSize(IValueConfiguration tournamentVc) {
+    private static void ConfigureTournamentGroupSize(ParameterizedValueConfiguration tournamentVc) {
       var groupSizePc = tournamentVc.ParameterConfigurations.Where(x => x.ParameterName == "GroupSize").SingleOrDefault();
       groupSizePc.Optimize = true;
-
-      groupSizePc.ValueConfigurations.First().Optimize = true;
-      groupSizePc.ValueConfigurations.First().RangeConstraint.LowerBound = new IntValue(0);
-      groupSizePc.ValueConfigurations.First().RangeConstraint.UpperBound = new IntValue(10);
-      groupSizePc.ValueConfigurations.First().RangeConstraint.StepSize = new IntValue(1);
-    }
-
-    private static void ConfigurePopulationSize(IValueConfiguration algorithmVc, int lower, int upper, int stepsize) {
+      var groupSizeVc = (RangeValueConfiguration)groupSizePc.ValueConfigurations.First();
+      groupSizeVc.Optimize = true;
+      groupSizeVc.RangeConstraint.LowerBound = new IntValue(0);
+      groupSizeVc.RangeConstraint.UpperBound = new IntValue(10);
+      groupSizeVc.RangeConstraint.StepSize = new IntValue(1);
+    }
+
+    private static void ConfigurePopulationSize(ParameterizedValueConfiguration algorithmVc, int lower, int upper, int stepsize) {
       var populationSizePc = algorithmVc.ParameterConfigurations.Where(x => x.Name == "PopulationSize").SingleOrDefault();
       populationSizePc.Optimize = true;
-      var populationSizeVc = populationSizePc.ValueConfigurations.First();
+      var populationSizeVc = (RangeValueConfiguration)populationSizePc.ValueConfigurations.First();
       populationSizeVc.Optimize = true;
       populationSizeVc.RangeConstraint.LowerBound = new IntValue(lower);
@@ -778,8 +787,8 @@
     }
 
-    private static void ConfigureMutationRate(IValueConfiguration algorithmVc, double lower, double upper, double stepsize) {
+    private static void ConfigureMutationRate(ParameterizedValueConfiguration algorithmVc, double lower, double upper, double stepsize) {
       var mutationRatePc = algorithmVc.ParameterConfigurations.Where(x => x.Name == "MutationProbability").SingleOrDefault();
       mutationRatePc.Optimize = true;
-      var mutationRateVc = mutationRatePc.ValueConfigurations.First();
+      var mutationRateVc = (RangeValueConfiguration)mutationRatePc.ValueConfigurations.First();
       mutationRateVc.Optimize = true;
       mutationRateVc.RangeConstraint.LowerBound = new PercentValue(lower);
@@ -788,8 +797,8 @@
     }
 
-    private static void ConfigureElites(IValueConfiguration algorithmVc, int from, int to, int stepSize) {
+    private static void ConfigureElites(ParameterizedValueConfiguration algorithmVc, int from, int to, int stepSize) {
       var elitesPc = algorithmVc.ParameterConfigurations.Where(x => x.Name == "Elites").SingleOrDefault();
       elitesPc.Optimize = true;
-      var elitesVc = elitesPc.ValueConfigurations.First();
+      var elitesVc = (RangeValueConfiguration)elitesPc.ValueConfigurations.First();
       elitesVc.Optimize = true;
       elitesVc.RangeConstraint.LowerBound = new IntValue(from);
@@ -855,22 +864,23 @@
                 var orderedRuns = rc.OrderBy(x => x.Results["AverageQualityNormalized"]);
 
-                TableBuilder tb = new TableBuilder("QNorm", "Qualities", "PoSi", "MutRa", /*"Eli",*/ "SelOp", "MutOp", "NrSelSubScopes");
+                TableBuilder tb = new TableBuilder("QNorm", "Qualities"/*, "PoSi"/* "MutRa", "Eli", "SelOp", "MutOp", "NrSelSubScopes"*/);
                 foreach (IRun run in orderedRuns) {
-                  string selector;
-                  if (run.Parameters["Selector"] is TournamentSelector) {
-                    selector = string.Format("{0} ({1})", run.Parameters["Selector"].ToString(), ((TournamentSelector)run.Parameters["Selector"]).GroupSizeParameter.Value.ToString());
-                  } else {
-                    selector = string.Format("{0}", run.Parameters["Selector"].ToString());
-                  }
+                  //string selector;
+                  //if (run.Parameters["Selector"] is TournamentSelector) {
+                  //  selector = string.Format("{0} ({1})", run.Parameters["Selector"].ToString(), ((TournamentSelector)run.Parameters["Selector"]).GroupSizeParameter.Value.ToString());
+                  //} else {
+                  //  selector = string.Format("{0}", run.Parameters["Selector"].ToString());
+                  //}
 
                   tb.AppendRow(
                     ((DoubleValue)run.Results["AverageQualityNormalized"]).Value.ToString("#0.0000"),
-                    ((DoubleArray)run.Results["RunsAverageQualities"]).ToString(),
-                    ((IntValue)run.Parameters["PopulationSize"]).Value.ToString(),
-                    ((DoubleValue)run.Parameters["MutationProbability"]).Value.ToString("0.0000"),
+                    ((DoubleArray)run.Results["RunsAverageQualities"]).ToString()
+                    //((IntValue)run.Parameters["PopulationSize"]).Value.ToString(),
+                    //((DoubleValue)run.Parameters["MutationProbability"]).Value.ToString("0.0000"),
                     //((IntValue)run.Parameters["Elites"]).Value.ToString(),
-                    Shorten(selector, 20),
-                    Shorten(run.Parameters.ContainsKey("Mutator") ? run.Parameters["Mutator"].ToString() : "null", 40),
-                    ((ISelector)run.Parameters["Selector"]).NumberOfSelectedSubScopesParameter.Value.ToString());
+                    //Shorten(selector, 20),
+                    //Shorten(run.Parameters.ContainsKey("Mutator") ? run.Parameters["Mutator"].ToString() : "null", 40),
+                    //((ISelector)run.Parameters["Selector"]).NumberOfSelectedSubScopesParameter.Value.ToString()
+                    );
                 }
                 sb.AppendLine(tb.ToString());
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.sln
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.sln	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.sln	(revision 5653)
@@ -10,5 +10,4 @@
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F96C8DD1-9B68-4F2D-AD4F-1A174F596041}"
 	ProjectSection(SolutionItems) = preProject
-		Performance1.psess = Performance1.psess
 		PreBuildEvent.cmd = PreBuildEvent.cmd
 	EndProjectSection
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/OptimizableView.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/OptimizableView.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/OptimizableView.cs	(revision 5653)
@@ -1,14 +1,6 @@
 ﻿using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
-using System.Linq;
-using System.Text;
 using HeuristicLab.Core.Views;
+using HeuristicLab.Data;
 using HeuristicLab.MainForm;
-using HeuristicLab.Parameters;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
 
 namespace HeuristicLab.Problems.MetaOptimization.Views.ValueConfigurationViews {
@@ -47,17 +39,27 @@
         if (Content.Optimize) {
           this.viewHost.ViewType = null;
-          if (Content is IParameterConfiguration) {
+
+          var pc = Content as IParameterConfiguration;
+          var vc = Content as IValueConfiguration;
+
+          if (pc != null) {
             this.viewHost.Content = ((IParameterConfiguration)Content).ValueConfigurations;
-          } else if (Content is IValueConfiguration) {
-            if (Content.ActualValue.ValueDataType == typeof(IntValue) ||
+          } else if(vc != null) {
+            var rvc = Content as RangeValueConfiguration;
+            if (rvc != null) {
+              if (Content.ActualValue.ValueDataType == typeof(IntValue) ||
                 Content.ActualValue.ValueDataType == typeof(DoubleValue) ||
                 Content.ActualValue.ValueDataType == typeof(PercentValue)) {
-              this.viewHost.ViewsLabelVisible = true;
-              this.viewHost.Content = ((IValueConfiguration)Content).RangeConstraint;
-            } else if(Content.ActualValue.ValueDataType == typeof(BoolValue)) {
-              this.viewHost.Content = null; // no configuration required
-            } else {
+                this.viewHost.ViewsLabelVisible = true;
+                this.viewHost.Content = rvc.RangeConstraint;
+              } else if (Content.ActualValue.ValueDataType == typeof(BoolValue)) {
+                this.viewHost.Content = null; // no configuration required
+              }
+            }
+
+            var pvc = Content as ParameterizedValueConfiguration;
+            if (pvc != null) {
               this.viewHost.ViewsLabelVisible = false;
-              this.viewHost.Content = ((IValueConfiguration)Content).ParameterConfigurations;
+              this.viewHost.Content = pvc.ParameterConfigurations;
             }
           } else {
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/ValueConfigurationViews/ValueConfigurationCheckedItemList.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/ValueConfigurationViews/ValueConfigurationCheckedItemList.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization.Views/3.3/ValueConfigurationViews/ValueConfigurationCheckedItemList.cs	(revision 5653)
@@ -1,15 +1,10 @@
 ﻿using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Drawing;
-using System.Data;
 using System.Linq;
-using System.Text;
+using System.Windows.Forms;
+using HeuristicLab.Collections;
+using HeuristicLab.Core;
 using HeuristicLab.Core.Views;
 using HeuristicLab.MainForm;
-using HeuristicLab.Core;
-using System.Windows.Forms;
 using HeuristicLab.PluginInfrastructure;
-using HeuristicLab.Collections;
 
 namespace HeuristicLab.Problems.MetaOptimization.Views {
@@ -76,7 +71,9 @@
           if (value is NullValue) {
             return new NullValueConfiguration();
+          } else if(value is IParameterizedItem) {
+            return new ParameterizedValueConfiguration(value, value.GetType());
           } else {
-            return new ValueConfiguration(value, value.GetType());
-          }
+            return new RangeValueConfiguration(value, value.GetType());
+          } 
         }
         catch (Exception ex) {
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/AlgorithmExecutor.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/AlgorithmExecutor.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/AlgorithmExecutor.cs	(revision 5653)
@@ -0,0 +1,43 @@
+﻿using System;
+using System.Threading;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+
+  public static class AlgorithmExtensions {
+    public static void StartSync(this IAlgorithm algorithm) {
+      var executor = new AlgorithmExecutor(algorithm);
+      executor.StartSync();
+    }
+  }
+
+  /// <summary>
+  /// Can execute an algorithm synchronously
+  /// </summary>
+  internal class AlgorithmExecutor {
+    private IAlgorithm algorithm;
+    private AutoResetEvent waitHandle = new AutoResetEvent(false);
+
+    public AlgorithmExecutor(IAlgorithm algorithm) {
+      this.algorithm = algorithm;
+    }
+
+    public void StartSync() {
+      algorithm.Stopped += new EventHandler(algorithm_Stopped);
+      algorithm.Paused += new EventHandler(algorithm_Paused);
+      algorithm.Start();
+      waitHandle.WaitOne();
+      waitHandle.Dispose();
+      algorithm.Stopped -= new EventHandler(algorithm_Stopped);
+      algorithm.Paused -= new EventHandler(algorithm_Paused);
+    }
+
+    void algorithm_Paused(object sender, EventArgs e) {
+      waitHandle.Set();
+    }
+
+    void algorithm_Stopped(object sender, EventArgs e) {
+      waitHandle.Set();
+    }
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/ReferenceQualityAnalyzer.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/ReferenceQualityAnalyzer.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/ReferenceQualityAnalyzer.cs	(revision 5653)
@@ -68,5 +68,5 @@
       DoubleArray referenceQualities = new DoubleArray(ProblemsParameter.ActualValue.Count);
       for (int pi = 0; pi < ProblemsParameter.ActualValue.Count; pi++) {
-        referenceQualities[pi] = solutions.Select(x => x.AverageQualities[pi]).Min(); // todo: respect minimization / maximization
+        referenceQualities[pi] = solutions.Where(x => x.AverageQualities != null).Select(x => x.AverageQualities[pi]).Min(); // todo: respect minimization / maximization
       }
       return referenceQualities;
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Crossovers/ParameterConfigurationCrossover.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Crossovers/ParameterConfigurationCrossover.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Crossovers/ParameterConfigurationCrossover.cs	(revision 5653)
@@ -97,5 +97,5 @@
 
     private static void Cross(IRandom random, IOptimizable configuartion, IOptimizable other, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
-      var vc = configuartion as IValueConfiguration;
+      var vc = configuartion as RangeValueConfiguration;
       var pc = configuartion as IParameterConfiguration;
       if (vc != null) {
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Manipulators/ParameterConfigurationManipulator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Manipulators/ParameterConfigurationManipulator.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/Manipulators/ParameterConfigurationManipulator.cs	(revision 5653)
@@ -1,13 +1,10 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+﻿using System.Linq;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
 using HeuristicLab.Operators;
 using HeuristicLab.Optimization;
-using HeuristicLab.Core;
 using HeuristicLab.Parameters;
-using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Data;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -55,5 +52,5 @@
 
     protected static void Mutate(IRandom random, IOptimizable configuration, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
-      var vc = configuration as IValueConfiguration;
+      var vc = configuration as RangeValueConfiguration;
       var pc = configuration as IParameterConfiguration;
 
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterCombinationsEnumerator.cs	(revision 5653)
@@ -1,7 +1,5 @@
 ﻿using System;
+using System.Collections;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Collections;
 using HeuristicLab.Core;
 
@@ -25,5 +23,5 @@
         if (!initialized)
           throw new SystemException("Enumeration not started. Call MoveNext!");
-        return Current; 
+        return Current;
       }
     }
@@ -94,21 +92,22 @@
       }
 
-      var vc = node as IValueConfiguration;
-      if (vc != null) {
-        if (vc.RangeConstraint != null) {
-          valueEnumerator = new EnumeratorCollectionEnumerator<IItem>();
-          valueEnumerator.AddEnumerator(vc.RangeConstraint.GetCombinations().GetEnumerator());
-          valueEnumerator.Reset();
-          enumerators.Add(valueEnumerator);
-        } else {
-          foreach (var parameterConfiguration in vc.ParameterConfigurations) {
-            if (parameterConfiguration.Optimize) {
-              var enumerator = new ParameterCombinationsEnumerator(parameterConfiguration);
-              enumerator.Reset();
-              enumerators.Add(enumerator);
-            }
+      var rangeVc = node as RangeValueConfiguration;
+      if (rangeVc != null) {
+        valueEnumerator = new EnumeratorCollectionEnumerator<IItem>();
+        valueEnumerator.AddEnumerator(rangeVc.RangeConstraint.GetCombinations().GetEnumerator());
+        valueEnumerator.Reset();
+        enumerators.Add(valueEnumerator);
+      }
+
+      var parameterizedVc = node as ParameterizedValueConfiguration;
+      if (parameterizedVc != null) {
+        foreach (var parameterConfiguration in parameterizedVc.ParameterConfigurations) {
+          if (parameterConfiguration.Optimize) {
+            var enumerator = new ParameterCombinationsEnumerator(parameterConfiguration);
+            enumerator.Reset();
+            enumerators.Add(enumerator);
           }
-          enumerators.Reverse(); // this makes the list of combinations better readable
         }
+        enumerators.Reverse(); // this makes the list of combinations better readable
       }
     }
@@ -129,5 +128,5 @@
     }
 
-    public void Dispose() {  }
+    public void Dispose() { }
 
     public T 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 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 5653)
@@ -1,17 +1,15 @@
 ﻿using System;
+using System.Collections;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
-using HeuristicLab.Common;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Optimization;
-using HeuristicLab.Data;
-using System.Collections;
 
 namespace HeuristicLab.Problems.MetaOptimization {
   // todo: storable, name, descr, ...
   [StorableClass]
-  public class ParameterConfigurationTree : ValueConfiguration, IEnumerable {
+  public class ParameterConfigurationTree : ParameterizedValueConfiguration, IEnumerable {
 
     [Storable]
@@ -189,5 +187,5 @@
     public Experiment GenerateExperiment(IAlgorithm algorithm, bool createBatchRuns, int repetitions) {
       Experiment experiment = new Experiment();
-      foreach (IValueConfiguration combination in this) {
+      foreach (ParameterizedValueConfiguration combination in this) {
         IAlgorithm clonedAlg = (IAlgorithm)algorithm.Clone();
         clonedAlg.Name = combination.ParameterInfoString;
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 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurations/ParameterConfiguration.cs	(revision 5653)
@@ -2,5 +2,8 @@
 using System.Collections;
 using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
+using System.Text;
+using HeuristicLab.Collections;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -9,9 +12,4 @@
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
 using HeuristicLab.PluginInfrastructure;
-using System.Text;
-using System.Reflection;
-using HeuristicLab.Optimization;
-using HeuristicLab.Collections;
-using System.Drawing;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -147,6 +145,6 @@
       this.ActualValue = new ConstrainedValue(
         valueParameter.Value != null ? valueParameter.Value : null, // don't clone here; otherwise settings of a non-optimized ValueParameter will not be synchronized with the ConstrainedValue
-        valueParameter.DataType, 
-        this.validValues != null ? new ItemSet<IItem>(this.validValues) : CreateValidValues(), 
+        valueParameter.DataType,
+        this.validValues != null ? new ItemSet<IItem>(this.validValues) : CreateValidValues(),
         this.IsNullable);
       if (Optimize) {
@@ -200,5 +198,5 @@
       if (this.ActualValue != null) this.ActualValue.ToStringChanged -= new EventHandler(ActualValue_ToStringChanged);
     }
-    
+
     private void PopulateValueConfigurations() {
       foreach (Type t in this.validTypes) {
@@ -212,5 +210,9 @@
             val = CreateItem(t);
           }
-          this.ValueConfigurations.Add(new ValueConfiguration(val, val.GetType()), true);
+          if (val is IParameterizedItem) {
+            this.ValueConfigurations.Add(new ParameterizedValueConfiguration(val, val.GetType()), true);
+          } else {
+            this.ValueConfigurations.Add(new RangeValueConfiguration(val, val.GetType()), true);
+          }
         }
       }
@@ -224,6 +226,6 @@
       // return only one type for ValueTypeValues<> (Int, Double, Percent, Bool). Otherwise 2 types would be returned for DoubleValue (PercentValue which is derived)
       if (IsSubclassOfRawGeneric(typeof(ValueTypeValue<>), parameter.DataType))
-        return new List<Type> { parameter.DataType }; 
-      
+        return new List<Type> { parameter.DataType };
+
       if (IsSubclassOfRawGeneric(typeof(OptionalConstrainedValueParameter<>), parameter.GetType())) {
         // use existing validvalues if known
@@ -252,8 +254,8 @@
       if (type == typeof(NullValue))
         return new NullValue();
-      
+
       // copy value from ValidValues; this ensures that previously set ActualNames for a type are kept
       IItem value = this.validValues.Where(v => v.GetType() == type).SingleOrDefault();
-      if (value != null) 
+      if (value != null)
         return value;
 
@@ -404,9 +406,9 @@
       if (Optimize) {
         if (this.ActualValue.Value is IParameterizedItem) {
-          this.ValueConfigurations[actualValueConfigurationIndex].Parameterize((IParameterizedItem)this.ActualValue.Value);
+          ((ParameterizedValueConfiguration)this.ValueConfigurations[actualValueConfigurationIndex]).Parameterize((IParameterizedItem)this.ActualValue.Value);
         }
       }
       var clonedValue = this.ActualValue.Value != null ? (IItem)this.ActualValue.Value.Clone() : null;
-      AdaptValidValues(parameter, clonedValue);
+      if(clonedValue != null) AdaptValidValues(parameter, clonedValue);
       parameter.Value = clonedValue;
     }
@@ -433,5 +435,5 @@
         foreach (var vc in this.ValueConfigurations) {
           if (this.ValueConfigurations.ItemChecked(vc)) {
-            vc.Randomize(random);
+            if (vc.Optimize) vc.Randomize(random);
           }
         }
@@ -447,5 +449,5 @@
         foreach (var vc in this.ValueConfigurations) {
           if (this.ValueConfigurations.ItemChecked(vc)) {
-            vc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
+            if (vc.Optimize) vc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
           }
         }
@@ -459,5 +461,5 @@
         for (int i = 0; i < this.ValueConfigurations.Count; i++) {
           if (this.ValueConfigurations.ItemChecked(this.ValueConfigurations[i])) {
-            this.ValueConfigurations[i].Cross(random, otherPc.ValueConfigurations[i], cross, intValueCrossover, doubleValueCrossover);
+            if (this.ValueConfigurations[i].Optimize) this.ValueConfigurations[i].Cross(random, otherPc.ValueConfigurations[i], cross, intValueCrossover, doubleValueCrossover);
           }
         }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/NullValueConfiguration.cs	(revision 5653)
@@ -1,9 +1,6 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
+﻿using System.Collections.Generic;
+using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.MetaOptimization {
@@ -12,5 +9,4 @@
 
     public NullValueConfiguration() {
-      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
       this.ActualValue = new ConstrainedValue(null, null, null, true);
       this.IsOptimizable = false;
@@ -28,4 +24,24 @@
       return "null";
     }
+
+    public override void Randomize(IRandom random) { }
+
+    public override void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) { }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) { }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      return 1.0;
+    }
+
+    public override string ParameterInfoString {
+      get { return "null"; }
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) { }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      return new List<IOptimizable>();
+    }
   }
 }
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 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ParameterizedValueConfiguration.cs	(revision 5653)
@@ -0,0 +1,160 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [StorableClass]
+  public class ParameterizedValueConfiguration : ValueConfiguration {
+    [Storable]
+    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
+    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
+      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
+      protected set { this.parameterConfigurations = value; }
+    }
+
+    public override bool Optimize {
+      get { return base.Optimize; }
+      set {
+        base.Optimize = value;
+        if (optimize) {
+          ClearParameterConfigurations();
+          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
+        } else {
+          ClearParameterConfigurations();
+        }
+      }
+    }
+
+    public override ConstrainedValue ActualValue {
+      get { return base.ActualValue; }
+      set {
+        ClearParameterConfigurations();
+        base.ActualValue = value;
+        if(this.actualValue.Value != null) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
+      }
+    }
+
+    #region Constructors and Cloning
+    [StorableConstructor]
+    protected ParameterizedValueConfiguration(bool deserializing) : base(deserializing) { }
+    public ParameterizedValueConfiguration() {
+      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
+    }
+    public ParameterizedValueConfiguration(IItem value, Type valueDataType)
+      : base(value, valueDataType) {
+    }
+    protected ParameterizedValueConfiguration(ParameterizedValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new ParameterizedValueConfiguration(this, cloner);
+    }
+    #endregion
+
+    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
+      foreach (var childParameter in parameterizedItem.Parameters) {
+        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
+        if (pc != null) this.parameterConfigurations.Add(pc);
+      }
+    }
+
+    protected virtual void ClearParameterConfigurations() {
+      parameterConfigurations.Clear();
+    }
+
+    public override string ParameterInfoString {
+      get {
+        StringBuilder sb = new StringBuilder();
+        if (this.Optimize && this.ParameterConfigurations.Count > 0) {
+          var parameterInfos = new List<string>();
+          foreach (var pc in this.ParameterConfigurations) {
+            if (pc.Optimize) parameterInfos.Add(pc.ParameterInfoString);
+          }
+          sb.Append(string.Join(", ", parameterInfos.ToArray()));
+        }
+        return sb.ToString();
+      }
+    }
+
+    public override string ToString() {
+      if (ActualValue != null && ActualValue.Value != null) {
+        if (Optimize) {
+          return string.Format("{0} (Optimize)", NumberedName);
+        } else {
+          return string.Format("{0}", NumberedName);
+        }
+      } else {
+        return base.ToString();
+      }
+    }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      var list = new List<IOptimizable>();
+      foreach (var pc in ParameterConfigurations) {
+        if (pc.Optimize) {
+          if (pc.ValueConfigurations.CheckedItems.Count() > 1) list.Add(pc); // only add if there are more than 1 choices. otherwise it makes no sense to optimize which VC is selected
+          list.AddRange(pc.GetAllOptimizables());
+        }
+      }
+      return list;
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
+      foreach (var pc in ParameterConfigurations) {
+        if (pc.Optimize) {
+          parameterNames.Add(prefix + pc.ParameterName);
+          pc.CollectOptimizedParameterNames(parameterNames, prefix + pc.ParameterName + ".");
+        }
+      }
+    }
+
+    public IEnumerable<string> GetOptimizedParameterNames() {
+      var list = new List<string>();
+      this.CollectOptimizedParameterNames(list, "");
+      return list;
+    }
+
+    public virtual void Parameterize(IParameterizedItem item) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
+      }
+    }
+
+    public override void Randomize(IRandom random) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Randomize(random);
+      }
+    }
+
+    public override void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
+      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
+        pc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
+      }
+    }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
+      var otherVc = (ParameterizedValueConfiguration)other;
+      for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
+        this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, intValueCrossover, doubleValueCrossover);
+      }
+    }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      var other = (ParameterizedValueConfiguration)optimizable;
+      double sum = 0;
+      int count = 0;
+      for (int i = 0; i < ParameterConfigurations.Count; i++) {
+        if (this.ParameterConfigurations.ElementAt(i).Optimize) {
+          sum += this.ParameterConfigurations.ElementAt(i).CalculateSimilarity(other.ParameterConfigurations.ElementAt(i));
+          count++;
+        }
+      }
+      return count == 0 ? 1.0 : sum / (double)count;
+    }
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/RangeValueConfiguration.cs	(revision 5653)
@@ -0,0 +1,110 @@
+﻿using System;
+using System.Collections.Generic;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Data;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [StorableClass]
+  public class RangeValueConfiguration : ValueConfiguration {
+    [Storable]
+    protected IRange rangeConstraint;
+    public IRange RangeConstraint {
+      get { return rangeConstraint; }
+      private set {
+        if (rangeConstraint != value) {
+          DeregisterRangeConstraintEvents();
+          rangeConstraint = value;
+          RegisterRangeConstraintEvents();
+        }
+      }
+    }
+
+    #region Constructor and Cloning
+    [StorableConstructor]
+    protected RangeValueConfiguration(bool deserializing) : base(deserializing) { }
+    public RangeValueConfiguration() {
+
+    }
+    protected RangeValueConfiguration(RangeValueConfiguration original, Cloner cloner)
+      : base(original, cloner) {
+      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
+      RegisterRangeConstraintEvents();
+    }
+    public RangeValueConfiguration(IItem value, Type valueDataType)
+      : base(value, valueDataType) {
+      if (actualValue.ValueDataType == typeof(IntValue)) {
+        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
+      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
+        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
+      } else if (actualValue.ValueDataType == typeof(PercentValue)) {
+        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.01));
+      } else if (actualValue.ValueDataType == typeof(BoolValue)) {
+        this.IsOptimizable = false; // there is nothing to configure for bools
+      } else {
+        RangeConstraint = null;
+      }
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new RangeValueConfiguration(this, cloner);
+    }
+    [StorableHook(HookType.AfterDeserialization)]
+    private void AfterDeserialization() {
+      RegisterRangeConstraintEvents();
+    }
+    #endregion
+
+    private void RegisterRangeConstraintEvents() {
+      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged += new EventHandler(RangeConstraint_ToStringChanged);
+    }
+    private void DeregisterRangeConstraintEvents() {
+      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged -= new EventHandler(RangeConstraint_ToStringChanged);
+    }
+
+    public override string ToString() {
+      if (ActualValue != null && ActualValue.Value != null) {
+        if (Optimize) {
+          return string.Format("{0} (Optimize: {1})", NumberedName, RangeConstraint);
+        } else {
+          return string.Format("{0}: {1}", NumberedName, ActualValue.Value);
+        }
+      } else {
+        return base.ToString();
+      }
+    }
+
+    public override void Randomize(IRandom random) {
+      this.actualValue.Value = rangeConstraint.GetRandomValue(random);
+    }
+
+    public override void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
+      mutate(random, this, intValueManipulator, doubleValueManipulator);
+    }
+
+    public override void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
+      cross(random, this, other, intValueCrossover, doubleValueCrossover);
+    }
+
+    public override double CalculateSimilarity(IOptimizable optimizable) {
+      var other = (IValueConfiguration)optimizable;
+      return this.RangeConstraint.CalculateSimilarity(this.ActualValue.Value, other.ActualValue.Value);
+    }
+
+    public override string ParameterInfoString {
+      get { return string.Empty; }
+    }
+
+    public override void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) { }
+
+    public override List<IOptimizable> GetAllOptimizables() {
+      return new List<IOptimizable>();
+    }
+
+    #region Events
+    private void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
+      OnToStringChanged();
+    }
+    #endregion
+  }
+}
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 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ValueConfigurations/ValueConfiguration.cs	(revision 5653)
@@ -1,19 +1,15 @@
 ﻿using System;
+using System.Collections.Generic;
+using System.Drawing;
 using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using HeuristicLab.Data;
-using System.Drawing;
-using HeuristicLab.Encodings.RealVectorEncoding;
-using HeuristicLab.Encodings.IntegerVectorEncoding;
 using HeuristicLab.PluginInfrastructure;
-using System.Collections.Generic;
-using System.Text;
 
 namespace HeuristicLab.Problems.MetaOptimization {
   // TODO: ItemName/Descr, storability
   [StorableClass]
-  public class ValueConfiguration : NamedItem, IValueConfiguration {
+  public abstract class ValueConfiguration : NamedItem, IValueConfiguration {
     public override bool CanChangeName {
       get { return true; }
@@ -38,26 +34,13 @@
     [Storable]
     protected bool optimize;
-    public bool Optimize {
+    public virtual bool Optimize {
       get { return optimize; }
       set {
         if (optimize != value) {
           optimize = value;
-          if (optimize) {
-            ClearParameterConfigurations();
-            if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
-          } else {
-            ClearParameterConfigurations();
-          }
           OnOptimizeChanged();
           OnToStringChanged();
         }
       }
-    }
-
-    [Storable]
-    protected IItemCollection<IParameterConfiguration> parameterConfigurations = new ItemCollection<IParameterConfiguration>();
-    public IItemCollection<IParameterConfiguration> ParameterConfigurations {
-      get { return new ReadOnlyItemCollection<IParameterConfiguration>(this.parameterConfigurations); }
-      protected set { this.parameterConfigurations = value; }
     }
 
@@ -69,22 +52,7 @@
         if (this.actualValue != value) {
           DeregisterActualValueEvents();
-          ClearParameterConfigurations();
           this.actualValue = value;
-          if (this.actualValue.Value is IParameterizedNamedItem) PopulateParameterConfigurations(this.actualValue.Value as IParameterizedNamedItem);
           OnValueChanged();
           OnToStringChanged();
-          RegisterActualValueEvents();
-        }
-      }
-    }
-
-    [Storable]
-    protected IRange rangeConstraint;
-    public IRange RangeConstraint {
-      get { return rangeConstraint; }
-      private set {
-        if (rangeConstraint != value) {
-          DeregisterRangeConstraintEvents();
-          rangeConstraint = value;
           RegisterActualValueEvents();
         }
@@ -106,19 +74,7 @@
     #region Constructors and Cloning
     public ValueConfiguration(IItem value, Type valueDataType) {
-      this.ParameterConfigurations = new ItemList<IParameterConfiguration>();
       var validTypes = ApplicationManager.Manager.GetTypes(valueDataType).OrderBy(x => x.Name).ToArray();
       this.ActualValue = new ConstrainedValue(value, valueDataType, new ItemSet<IItem> { value }, false);
       this.IsOptimizable = true;
-      if (actualValue.ValueDataType == typeof(IntValue)) {
-        RangeConstraint = new IntValueRange(new IntValue(0), (IntValue)value, new IntValue(1));
-      } else if (actualValue.ValueDataType == typeof(DoubleValue)) {
-        RangeConstraint = new DoubleValueRange(new DoubleValue(0), (DoubleValue)value, new DoubleValue(0.01));
-      } else if (actualValue.ValueDataType == typeof(PercentValue)) {
-        RangeConstraint = new PercentValueRange(new PercentValue(0), new PercentValue(1), new PercentValue(0.01));
-      } else if (actualValue.ValueDataType == typeof(BoolValue)) {
-        this.IsOptimizable = false; // there is nothing to configure for bools
-      } else {
-        RangeConstraint = null;
-      }
     }
 
@@ -128,38 +84,12 @@
     protected ValueConfiguration(ValueConfiguration original, Cloner cloner)
       : base(original, cloner) {
-      this.ParameterConfigurations = cloner.Clone(original.parameterConfigurations);
       this.actualValue = cloner.Clone(original.ActualValue);
-      this.rangeConstraint = cloner.Clone(original.RangeConstraint);
       this.isOptimizable = original.isOptimizable;
       this.optimize = original.optimize;
       this.number = original.number;
       RegisterActualValueEvents();
-      RegisterRangeConstraintEvents();
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ValueConfiguration(this, cloner);
-    }
-    [StorableHook(HookType.AfterDeserialization)]
-    private void AfterDeserialization() {
-      RegisterRangeConstraintEvents();
     }
     #endregion
 
-    protected virtual void PopulateParameterConfigurations(IParameterizedNamedItem parameterizedItem) {
-      foreach (var childParameter in parameterizedItem.Parameters) {
-        var pc = ParameterConfiguration.Create(parameterizedItem, childParameter);
-        if (pc != null) this.parameterConfigurations.Add(pc);
-      }
-    }
-    protected virtual void ClearParameterConfigurations() {
-      parameterConfigurations.Clear();
-    }
-
-    private void RegisterRangeConstraintEvents() {
-      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged += new EventHandler(RangeConstraint_ToStringChanged);
-    }
-    private void DeregisterRangeConstraintEvents() {
-      if (this.RangeConstraint != null) this.RangeConstraint.ToStringChanged -= new EventHandler(RangeConstraint_ToStringChanged);
-    }
     private void RegisterActualValueEvents() {
       if (this.actualValue != null) this.actualValue.ToStringChanged += new EventHandler(actualValue_ToStringChanged);
@@ -170,8 +100,5 @@
 
     #region Events
-    void actualValue_ToStringChanged(object sender, EventArgs e) {
-      OnToStringChanged();
-    }
-    void RangeConstraint_ToStringChanged(object sender, EventArgs e) {
+    private void actualValue_ToStringChanged(object sender, EventArgs e) {
       OnToStringChanged();
     }
@@ -212,26 +139,4 @@
     #endregion
 
-    public override string ToString() {
-      if (ActualValue != null && ActualValue.Value != null) {
-        string name = NumberedName;
-
-        if (ActualValue.Value is IParameterizedItem) {
-          if (Optimize) {
-            return string.Format("{0} (Optimize)", name);
-          } else {
-            return string.Format("{0}", name);
-          }
-        } else {
-          if (Optimize) {
-            return string.Format("{0} (Optimize: {1})", name, RangeConstraint);
-          } else {
-            return string.Format("{0}: {1}", name, ActualValue.Value);
-          }
-        }
-      } else {
-        return base.ToString();
-      }
-    }
-
     public string NumberedName {
       get {
@@ -244,103 +149,11 @@
     }
 
-    public string ParameterInfoString {
-      get {
-        StringBuilder sb = new StringBuilder();
-        if (this.Optimize && this.ParameterConfigurations.Count > 0) {
-          var parameterInfos = new List<string>();
-          foreach (var pc in this.ParameterConfigurations) {
-            if (pc.Optimize) parameterInfos.Add(pc.ParameterInfoString);
-          }
-          sb.Append(string.Join(", ", parameterInfos.ToArray()));
-        }
-        return sb.ToString();
-      }
-    }
-
-    public virtual void Parameterize(IParameterizedItem item) {
-      foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-        pc.Parameterize((IValueParameter)item.Parameters[pc.ParameterName]);
-      }
-    }
-
-    public void Randomize(IRandom random) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          this.actualValue.Value = rangeConstraint.GetRandomValue(random);
-        } else {
-          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-            pc.Randomize(random);
-          }
-        }
-      }
-    }
-
-    public void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          mutate(random, this, intValueManipulator, doubleValueManipulator);
-        } else {
-          foreach (IParameterConfiguration pc in this.ParameterConfigurations) {
-            pc.Mutate(random, mutate, intValueManipulator, doubleValueManipulator);
-          }
-        }
-      }
-    }
-
-    public void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover) {
-      if (Optimize) {
-        if (rangeConstraint != null) {
-          cross(random, this, other, intValueCrossover, doubleValueCrossover);
-        } else {
-          IValueConfiguration otherVc = (IValueConfiguration)other;
-          for (int i = 0; i < this.ParameterConfigurations.Count; i++) {
-            this.ParameterConfigurations.ElementAt(i).Cross(random, otherVc.ParameterConfigurations.ElementAt(i), cross, intValueCrossover, doubleValueCrossover);
-          }
-        }
-      }
-    }
-
-    public List<IOptimizable> GetAllOptimizables() {
-      var list = new List<IOptimizable>();
-      foreach (var pc in ParameterConfigurations) {
-        if (pc.Optimize) {
-          if (pc.ValueConfigurations.CheckedItems.Count() > 1) list.Add(pc); // only add if there are more than 1 choices. otherwise it makes no sense to optimize which VC is selected
-          list.AddRange(pc.GetAllOptimizables());
-        }
-      }
-      return list;
-    }
-
-    public void CollectOptimizedParameterNames(List<string> parameterNames, string prefix) {
-      foreach (var pc in ParameterConfigurations) {
-        if (pc.Optimize) {
-          parameterNames.Add(prefix + pc.ParameterName);
-          pc.CollectOptimizedParameterNames(parameterNames, prefix + pc.ParameterName + ".");
-        }
-      }
-    }
-
-    public IEnumerable<string> GetOptimizedParameterNames() {
-      var list = new List<string>();
-      this.CollectOptimizedParameterNames(list, "");
-      return list;
-    }
-
-    public double CalculateSimilarity(IOptimizable optimizable) {
-      var other = (IValueConfiguration)optimizable;
-      if (rangeConstraint != null) {
-        return this.RangeConstraint.CalculateSimilarity(this.ActualValue.Value, other.ActualValue.Value);
-      } else {
-        double sum = 0;
-        int count = 0;
-        for (int i = 0; i < ParameterConfigurations.Count; i++) {
-          if (this.ParameterConfigurations.ElementAt(i).Optimize) {
-            sum += this.ParameterConfigurations.ElementAt(i).CalculateSimilarity(other.ParameterConfigurations.ElementAt(i));
-            count++;
-          }
-        }
-        return count == 0 ? 1.0 : sum / (double)count;
-      }
-    }
+    public abstract void Randomize(IRandom random);
+    public abstract void Mutate(IRandom random, MutateDelegate mutate, IIntValueManipulator intValueManipulator, IDoubleValueManipulator doubleValueManipulator);
+    public abstract void Cross(IRandom random, IOptimizable other, CrossDelegate cross, IIntValueCrossover intValueCrossover, IDoubleValueCrossover doubleValueCrossover);
+    public abstract double CalculateSimilarity(IOptimizable optimizable);
+    public abstract string ParameterInfoString { get; }
+    public abstract void CollectOptimizedParameterNames(List<string> parameterNames, string prefix);
+    public abstract List<IOptimizable> GetAllOptimizables();
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmEvaluator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmEvaluator.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmEvaluator.cs	(revision 5653)
@@ -0,0 +1,78 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using System.Diagnostics;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [Item("AlgorithmEvaluator", "")]
+  [StorableClass]
+  public class AlgorithmEvaluator : SingleSuccessorOperator {
+
+    #region Parameter properties
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<IAlgorithm> AlgorithmParameter {
+      get { return (LookupParameter<IAlgorithm>)Parameters["Algorithm"]; }
+    }
+    public ILookupParameter<IntValue> ProblemIndexParameter {
+      get { return (LookupParameter<IntValue>)Parameters["ProblemIndex"]; }
+    }
+    public ILookupParameter<IntValue> RepetitionIndexParameter {
+      get { return (LookupParameter<IntValue>)Parameters["RepetitionIndex"]; }
+    }
+    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public IValueParameter<IItemList<IRun>> RunsParameter {
+      get { return (IValueParameter<IItemList<IRun>>)Parameters["Runs"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected AlgorithmEvaluator(bool deserializing) : base(deserializing) { }
+    public AlgorithmEvaluator()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
+      Parameters.Add(new LookupParameter<IAlgorithm>("Algorithm", ""));
+      Parameters.Add(new LookupParameter<IntValue>("ProblemIndex", ""));
+      Parameters.Add(new LookupParameter<IntValue>("RepetitionIndex", ""));
+      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new ValueParameter<IItemList<IRun>>("Runs", ""));
+    }
+    protected AlgorithmEvaluator(AlgorithmEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlgorithmEvaluator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      IAlgorithm algorithm = AlgorithmParameter.ActualValue;
+
+      var sw = new Stopwatch();
+      sw.Start();
+      algorithm.StartSync();
+      sw.Stop();
+      Console.WriteLine("{0},{1}: {2}", ProblemIndexParameter.ActualValue.Value, RepetitionIndexParameter.ActualValue.Value, sw.Elapsed);
+
+      RunsParameter.Value = new ItemList<IRun>(algorithm.Runs);
+
+      return base.Apply();
+    }
+
+    /// <summary>
+    /// This method should repair an invalid parameterConfiguration.
+    /// The strategy is to just randomize parameter settings. It's not guaranteed to be a vaild setting
+    /// </summary>
+    private void Repair(ParameterConfigurationTree parameterConfiguration, IRandom random) {
+      parameterConfiguration.Randomize(random);
+    }
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmExecutor.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmExecutor.cs	(revision 5576)
+++ 	(revision )
@@ -1,38 +1,0 @@
-﻿using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using HeuristicLab.Optimization;
-using System.Threading;
-
-namespace HeuristicLab.Problems.MetaOptimization {
-  /// <summary>
-  /// Can execute an algorithm synchronously
-  /// </summary>
-  public class AlgorithmExecutor {
-    private IAlgorithm algorithm;
-    private AutoResetEvent waitHandle = new AutoResetEvent(false);
-
-    public AlgorithmExecutor(IAlgorithm algorithm) {
-      this.algorithm = algorithm;
-    }
-
-    public void StartSync() {
-      algorithm.Stopped += new EventHandler(algorithm_Stopped);
-      algorithm.Paused += new EventHandler(algorithm_Paused);
-      algorithm.Start();
-      waitHandle.WaitOne();
-      waitHandle.Dispose();
-      algorithm.Stopped -= new EventHandler(algorithm_Stopped);
-      algorithm.Paused -= new EventHandler(algorithm_Paused);
-    }
-
-    void algorithm_Paused(object sender, EventArgs e) {
-      waitHandle.Set();
-    }
-
-    void algorithm_Stopped(object sender, EventArgs e) {
-      waitHandle.Set();
-    }
-  }
-}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmRunsAnalyzer.cs	(revision 5653)
@@ -0,0 +1,147 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [Item("AlgorithmRunsAnalyzer", "")]
+  [StorableClass]
+  public class AlgorithmRunsAnalyzer : SingleSuccessorOperator {
+
+    #region Parameter properties
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+    public LookupParameter<IntValue> RepetitionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[MetaOptimizationProblem.RepetitionsParameterName]; }
+    }
+    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public ILookupParameter<IItemList<IProblem>> ProblemsParameter {
+      get { return (ILookupParameter<IItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
+    }
+    public LookupParameter<DoubleArray> ProblemQualityReferencesParameter {
+      get { return (LookupParameter<DoubleArray>)Parameters["ProblemQualityReferences"]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public ScopeTreeLookupParameter<IAlgorithm> AlgorithmParameter {
+      get { return (ScopeTreeLookupParameter<IAlgorithm>)Parameters["Algorithm"]; }
+    }
+    public ScopeTreeLookupParameter<IntValue> ProblemIndexParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["ProblemIndex"]; }
+    }
+    public ScopeTreeLookupParameter<IntValue> RepetitionIndexParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["RepetitionIndex"]; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected AlgorithmRunsAnalyzer(bool deserializing) : base(deserializing) { }
+    public AlgorithmRunsAnalyzer() : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the ParameterVector."));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", ""));
+      Parameters.Add(new LookupParameter<IntValue>(MetaOptimizationProblem.RepetitionsParameterName, "Number of evaluations on one problem."));
+      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new LookupParameter<IItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, ""));
+      Parameters.Add(new LookupParameter<DoubleArray>("ProblemQualityReferences", ""));
+      Parameters.Add(new LookupParameter<ResultCollection>("Results", ""));
+      Parameters.Add(new ScopeTreeLookupParameter<IAlgorithm>("Algorithm", "The finished algorithms containing Runs."));
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("ProblemIndex", "The index of the problem an algorithm was executed with."));
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("RepetitionIndex", "The index of the repetition"));
+    }
+    protected AlgorithmRunsAnalyzer(AlgorithmRunsAnalyzer original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlgorithmRunsAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ParameterConfigurationTree parameterConfiguration = ParameterConfigurationParameter.ActualValue;
+      ItemArray<IAlgorithm> algorithms = AlgorithmParameter.ActualValue;
+      ItemArray<IntValue> problemIndices = ProblemIndexParameter.ActualValue;
+      ItemArray<IntValue> repetitionIndices = RepetitionIndexParameter.ActualValue;
+      IEnumerable<string> parameterNames = parameterConfiguration.GetOptimizedParameterNames();
+      IItemList<IProblem> problems = ProblemsParameter.ActualValue;
+      int repetitions = RepetitionsParameter.ActualValue.Value;
+      var resultNames = new List<string> { "BestQuality", "Execution Time" };
+      int currentGeneration = GenerationsParameter.ActualValue != null ? GenerationsParameter.ActualValue.Value : 0;
+      double[] referenceQualities = GetReferenceQualities(problems.Count);
+      ResultCollection results = ResultsParameter.ActualValue;
+
+      if (algorithms.All(x => x.Runs.Count == 1)) {
+        var runs = new RunCollection();
+        var qualities = new double[problems.Count][];
+        var executionTimes = new TimeSpan[problems.Count][];
+
+        for (int i = 0; i < problems.Count; i++) {
+          qualities[i] = new double[repetitions];
+          executionTimes[i] = new TimeSpan[repetitions];
+        }
+
+        for (int i = 0; i < algorithms.Length; i++) {
+          int problemIndex = problemIndices[i].Value;
+          int repetitionIndex = repetitionIndices[i].Value;
+
+          IRun run = algorithms[i].Runs.First();
+          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.Name = string.Format("{0} Problem {1} Run {2}", parameterConfiguration.ParameterInfoString, problemIndex, repetitionIndex);
+          qualities[problemIndex][repetitionIndex] = (((DoubleValue)run.Results["BestQuality"]).Value);
+          executionTimes[problemIndex][repetitionIndex] = (((TimeSpanValue)run.Results["Execution Time"]).Value);
+          runs.Add((IRun)run.Clone());
+        }
+
+        parameterConfiguration.AverageExecutionTimes = new ItemList<TimeSpanValue>(executionTimes.Select(t => new TimeSpanValue(TimeSpan.FromMilliseconds(t.Average(ts => ts.TotalMilliseconds)))));
+        parameterConfiguration.Repetitions = new IntValue(repetitions);
+        parameterConfiguration.BestQualities = new DoubleArray(qualities.Select(q => q.Min()).ToArray()); // todo: respect Maximization:true/false
+        parameterConfiguration.AverageQualities = new DoubleArray(qualities.Select(q => q.Average()).ToArray());
+        parameterConfiguration.WorstQualities = new DoubleArray(qualities.Select(q => q.Max()).ToArray()); // todo: respect Maximization:true/false
+        parameterConfiguration.QualityVariances = new DoubleArray(qualities.Select(q => q.Variance()).ToArray());
+        parameterConfiguration.QualityStandardDeviations = new DoubleArray(qualities.Select(q => q.StandardDeviation()).ToArray());
+        parameterConfiguration.Runs = runs;
+
+        this.QualityParameter.ActualValue = new DoubleValue(MetaOptimizationUtil.NormalizeQualities(parameterConfiguration, referenceQualities));
+      } else {
+        // something terrible happened -> most probably due to invalid parameters.
+        // penalty with worst quality from latest generation!
+
+        double penaltyValue = results.ContainsKey("CurrentWorstQuality") ? ((DoubleValue)results["CurrentWorstQuality"]).Value : referenceQualities.Max(); // todo: respect min/max
+        this.QualityParameter.ActualValue = new DoubleValue(penaltyValue);
+      }
+
+      return base.Apply();
+    }
+
+    private double[] GetReferenceQualities(int problemsCount) {
+      double[] referenceQualities;
+      if (ProblemQualityReferencesParameter.ActualValue == null) {
+        // this is generation zero. no reference qualities for normalization have been calculated yet. in this special case the ReferenceQualityAnalyzer will do the normalization
+        referenceQualities = new double[problemsCount];
+        for (int i = 0; i < referenceQualities.Length; i++) {
+          referenceQualities[i] = 1;
+        }
+      } else {
+        referenceQualities = ProblemQualityReferencesParameter.ActualValue.ToArray();
+      }
+      return referenceQualities;
+    }
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmSubScopesCreator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmSubScopesCreator.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/AlgorithmSubScopesCreator.cs	(revision 5653)
@@ -0,0 +1,82 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Parameters;
+using HeuristicLab.Optimization;
+using HeuristicLab.Data;
+using HeuristicLab.Algorithms.GeneticAlgorithm;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [Item("ChildrenCreator", "An operator which is used to prepare crossover. The sub-scopes of the current scope the operator is applied on represent the parents. The operator creates new and empty scopes for each child, adds the scopes that represent the child's parents as sub-scopes to the child and adds the child as sub-scope to the current scope.")]
+  [StorableClass]
+  public class AlgorithmSubScopesCreator : SingleSuccessorOperator {
+    #region Parameter properties
+    public ILookupParameter<TypeValue> AlgorithmTypeParameter {
+      get { return (ILookupParameter<TypeValue>)Parameters[MetaOptimizationProblem.AlgorithmTypeParameterName]; }
+    }
+    public ILookupParameter<IItemList<IProblem>> ProblemsParameter {
+      get { return (ILookupParameter<IItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
+    }
+    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public LookupParameter<IntValue> RepetitionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[MetaOptimizationProblem.RepetitionsParameterName]; }
+    }
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected AlgorithmSubScopesCreator(bool deserializing) : base(deserializing) { }
+    public AlgorithmSubScopesCreator()
+      : base() {
+      Parameters.Add(new LookupParameter<TypeValue>(MetaOptimizationProblem.AlgorithmTypeParameterName, ""));
+      Parameters.Add(new LookupParameter<IItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, ""));
+      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new LookupParameter<IntValue>(MetaOptimizationProblem.RepetitionsParameterName, "Number of evaluations on one problem."));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope whose sub-scopes represent the parents."));
+    }
+    protected AlgorithmSubScopesCreator(AlgorithmSubScopesCreator original, Cloner cloner)
+      : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new AlgorithmSubScopesCreator(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ParameterConfigurationTree parameterConfiguration = ParameterConfigurationParameter.ActualValue;
+      IItemList<IProblem> problems = ProblemsParameter.ActualValue;
+      int repetitions = RepetitionsParameter.ActualValue.Value;
+      Type algorithmType = AlgorithmTypeParameter.ActualValue.Value;
+
+      for (int i = 0; i < repetitions; i++) {
+        for (int j = 0; j < problems.Count; j++) {
+          IScope child = new Scope(string.Format("Problem {0}, Repetition {1}", j, i));
+          var algorithm = (IAlgorithm)Activator.CreateInstance(algorithmType);
+          algorithm.Problem = (IProblem)problems[j].Clone();
+          ((EngineAlgorithm)algorithm).Engine = new SequentialEngine.SequentialEngine();
+
+          //((GeneticAlgorithm)algorithm).PopulationSize.Value = 10;
+          //((GeneticAlgorithm)algorithm).MaximumGenerations.Value = 10;
+
+          parameterConfiguration.Parameterize(algorithm);
+          child.Variables.Add(new Variable("Algorithm", algorithm));
+          child.Variables.Add(new Variable("ProblemIndex", new IntValue(j)));
+          child.Variables.Add(new Variable("RepetitionIndex", new IntValue(i)));
+          CurrentScope.SubScopes.Add(child);
+        }
+      }
+      return base.Apply();
+    }
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/PMOEvaluator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/PMOEvaluator.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/PMOEvaluator.cs	(revision 5653)
@@ -0,0 +1,91 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Common;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+using HeuristicLab.Optimization;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  [Item("PMOEvaluator", "An operator which represents the main loop of a genetic algorithm.")]
+  [StorableClass]
+  public class PMOEvaluator : AlgorithmOperator, IParameterConfigurationEvaluator {
+
+    #region Parameter properties
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
+    }
+    public ILookupParameter<DoubleValue> QualityParameter {
+      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ILookupParameter<TypeValue> AlgorithmTypeParameter {
+      get { return (ILookupParameter<TypeValue>)Parameters[MetaOptimizationProblem.AlgorithmTypeParameterName]; }
+    }
+    public ILookupParameter<IItemList<IProblem>> ProblemsParameter {
+      get { return (ILookupParameter<IItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
+    }
+    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public LookupParameter<IntValue> RepetitionsParameter {
+      get { return (LookupParameter<IntValue>)Parameters[MetaOptimizationProblem.RepetitionsParameterName]; }
+    }
+    public LookupParameter<DoubleArray> ProblemQualityReferencesParameter {
+      get { return (LookupParameter<DoubleArray>)Parameters["ProblemQualityReferences"]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+    public LookupParameter<ResultCollection> ResultsParameter {
+      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    private ScopeParameter CurrentScopeParameter {
+      get { return (ScopeParameter)Parameters["CurrentScope"]; }
+    }
+    public IScope CurrentScope {
+      get { return CurrentScopeParameter.ActualValue; }
+    }
+    #endregion
+
+    [StorableConstructor]
+    protected PMOEvaluator(bool deserializing) : base(deserializing) { }
+    public PMOEvaluator() {
+      Initialize();
+    }
+    protected PMOEvaluator(PMOEvaluator original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PMOEvaluator(this, cloner);
+    }
+
+    private void Initialize() {
+      #region Create parameters
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
+      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the ParameterVector."));
+      Parameters.Add(new LookupParameter<TypeValue>(MetaOptimizationProblem.AlgorithmTypeParameterName, ""));
+      Parameters.Add(new LookupParameter<IItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, ""));
+      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new LookupParameter<IntValue>(MetaOptimizationProblem.RepetitionsParameterName, "Number of evaluations on one problem."));
+      Parameters.Add(new LookupParameter<DoubleArray>("ProblemQualityReferences", ""));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", ""));
+      Parameters.Add(new ScopeParameter("CurrentScope", "The current scope which represents a population of solutions on which the genetic algorithm should be applied."));
+      #endregion
+      
+      var algorithmSubScopesCreator = new AlgorithmSubScopesCreator();
+      var uniformSubScopesProcessor = new UniformSubScopesProcessor();
+      var algorithmEvaluator = new AlgorithmEvaluator();
+      var algorithmRunsAnalyzer = new AlgorithmRunsAnalyzer();
+
+      this.OperatorGraph.InitialOperator = algorithmSubScopesCreator;
+      algorithmSubScopesCreator.Successor = uniformSubScopesProcessor;
+      uniformSubScopesProcessor.Operator = algorithmEvaluator;
+      uniformSubScopesProcessor.Successor = algorithmRunsAnalyzer;
+      algorithmRunsAnalyzer.Successor = null;
+
+    }
+
+  }
+}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/ParameterConfigurationEvaluator.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Evaluators/ParameterConfigurationEvaluator.cs	(revision 5576)
+++ 	(revision )
@@ -1,197 +1,0 @@
-﻿using System;
-using System.Linq;
-using System.Threading;
-using HeuristicLab.Common;
-using HeuristicLab.Core;
-using HeuristicLab.Data;
-using HeuristicLab.Operators;
-using HeuristicLab.Optimization;
-using HeuristicLab.Parameters;
-using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
-using System.Collections.Generic;
-using HeuristicLab.Algorithms.GeneticAlgorithm;
-using System.Threading.Tasks;
-using System.Diagnostics;
-using System.Reflection;
-
-namespace HeuristicLab.Problems.MetaOptimization {
-  /// <summary>
-  /// A base class for operators which evaluate TSP solutions.
-  /// </summary>
-  [Item("ParameterConfigurationEvaluator", "A base class for operators which evaluate Meta Optimization solutions.")]
-  [StorableClass]
-  public class ParameterConfigurationEvaluator : SingleSuccessorOperator, IParameterConfigurationEvaluator, IStochasticOperator {
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (LookupParameter<IRandom>)Parameters["Random"]; }
-    }
-    public ILookupParameter<DoubleValue> QualityParameter {
-      get { return (ILookupParameter<DoubleValue>)Parameters["Quality"]; }
-    }
-    public ILookupParameter<TypeValue> AlgorithmTypeParameter {
-      get { return (ILookupParameter<TypeValue>)Parameters[MetaOptimizationProblem.AlgorithmTypeParameterName]; }
-    }
-    public ILookupParameter<IItemList<IProblem>> ProblemsParameter {
-      get { return (ILookupParameter<IItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
-    }
-    public ILookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
-      get { return (ILookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
-    }
-    public LookupParameter<IntValue> RepetitionsParameter {
-      get { return (LookupParameter<IntValue>)Parameters[MetaOptimizationProblem.RepetitionsParameterName]; }
-    }
-
-    public LookupParameter<DoubleArray> ProblemQualityReferencesParameter {
-      get { return (LookupParameter<DoubleArray>)Parameters["ProblemQualityReferences"]; }
-    }
-    public LookupParameter<IntValue> GenerationsParameter {
-      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
-    }
-    public LookupParameter<ResultCollection> ResultsParameter {
-      get { return (LookupParameter<ResultCollection>)Parameters["Results"]; }
-    }
-    
-    public IntValue Repetitions {
-      get { return RepetitionsParameter.ActualValue; }
-    }
-
-    public ParameterConfigurationEvaluator()
-      : base() {
-      Parameters.Add(new LookupParameter<IRandom>("Random", "The pseudo random number generator which should be used to initialize the new random permutation."));
-      Parameters.Add(new LookupParameter<DoubleValue>("Quality", "The evaluated quality of the ParameterVector."));
-      Parameters.Add(new LookupParameter<TypeValue>(MetaOptimizationProblem.AlgorithmTypeParameterName, "Missing description."));
-      Parameters.Add(new LookupParameter<IItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName, "Missing description."));
-      Parameters.Add(new LookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", "Missing description."));
-      Parameters.Add(new LookupParameter<IntValue>(MetaOptimizationProblem.RepetitionsParameterName, "Number of evaluations on one problem."));
-      Parameters.Add(new LookupParameter<DoubleArray>("ProblemQualityReferences", ""));
-      Parameters.Add(new LookupParameter<IntValue>("Generations", ""));
-      Parameters.Add(new LookupParameter<ResultCollection>("Results", ""));
-    }
-
-    [StorableConstructor]
-    protected ParameterConfigurationEvaluator(bool deserializing) : base(deserializing) { }
-    protected ParameterConfigurationEvaluator(ParameterConfigurationEvaluator original, Cloner cloner)
-      : base(original, cloner) {
-    }
-    public override IDeepCloneable Clone(Cloner cloner) {
-      return new ParameterConfigurationEvaluator(this, cloner);
-    }
-
-    public override IOperation Apply() {
-      IRandom random = RandomParameter.ActualValue;
-      ParameterConfigurationTree parameterConfiguration = ParameterConfigurationParameter.ActualValue;
-      IAlgorithm algorithm = (IAlgorithm)Activator.CreateInstance(AlgorithmTypeParameter.ActualValue.Value);
-      IItemList<IProblem> problems = ProblemsParameter.ActualValue;
-      ItemDictionary<StringValue, RunCollection> solutionCache = ResultsParameter.ActualValue.ContainsKey("SolutionCache") ? (ItemDictionary<StringValue, RunCollection>)ResultsParameter.ActualValue["SolutionCache"].Value : null;
-      double[] referenceQualities = GetReferenceQualities(problems);
-      int currentGeneration = GenerationsParameter.ActualValue != null ? GenerationsParameter.ActualValue.Value : 0;
-      int repetitions = Repetitions.Value;
-
-      RunCollection runs;
-      if (solutionCache != null && solutionCache.Count(x => x.Key.Value == parameterConfiguration.ParameterInfoString) > 0) {
-        runs = solutionCache.Single(x => x.Key.Value == parameterConfiguration.ParameterInfoString).Value;
-      } else {
-        do {
-          runs = ExecuteAlgorithm(parameterConfiguration, algorithm, problems, repetitions, currentGeneration);
-          if (runs == null) {
-            Repair(parameterConfiguration, random);
-            parameterConfiguration.Parameterize(algorithm);
-          }
-        } while (runs == null);
-      }
-      
-      List<List<double>> qualities = new List<List<double>>();
-      List<List<TimeSpan>> executionTimes = new List<List<TimeSpan>>();
-
-      for (int i = 0; i < problems.Count; i++) {
-        var problemRuns = runs.Where(x => ((IntValue)x.Results["Meta.ProblemIndex"]).Value == i + 1);
-        qualities.Add(problemRuns.Select(x => ((DoubleValue)x.Results["BestQuality"]).Value).ToList());
-        executionTimes.Add(problemRuns.Select(x => ((TimeSpanValue)x.Results["Execution Time"]).Value).ToList());
-      }
-
-      parameterConfiguration.AverageExecutionTimes = new ItemList<TimeSpanValue>(executionTimes.Select(t => new TimeSpanValue(TimeSpan.FromMilliseconds(t.Average(ts => ts.TotalMilliseconds)))));
-      parameterConfiguration.Repetitions = (IntValue)Repetitions.Clone();
-      parameterConfiguration.BestQualities = new DoubleArray(qualities.Select(q => q.Min()).ToArray()); // todo: respect Maximization:true/false
-      parameterConfiguration.AverageQualities = new DoubleArray(qualities.Select(q => q.Average()).ToArray());
-      parameterConfiguration.WorstQualities = new DoubleArray(qualities.Select(q => q.Max()).ToArray()); // todo: respect Maximization:true/false
-      parameterConfiguration.QualityVariances = new DoubleArray(qualities.Select(q => q.Variance()).ToArray());
-      parameterConfiguration.QualityStandardDeviations = new DoubleArray(qualities.Select(q => q.StandardDeviation()).ToArray());
-      parameterConfiguration.Runs = (RunCollection)runs.Clone();
-
-      this.QualityParameter.ActualValue = new DoubleValue(MetaOptimizationUtil.NormalizeQualities(parameterConfiguration, referenceQualities));
-
-      return base.Apply();
-    }
-
-    /// <summary>
-    /// This method should repair an invalid parameterConfiguration.
-    /// The strategy is to just randomize parameter settings. It's not guaranteed to be a vaild setting
-    /// </summary>
-    private void Repair(ParameterConfigurationTree parameterConfiguration, IRandom random) {
-      parameterConfiguration.Randomize(random);
-    }
-
-    private double[] GetReferenceQualities(IItemList<IProblem> problems) {
-      double[] referenceQualities;
-      if (ProblemQualityReferencesParameter.ActualValue == null) {
-        // this is generation zero. no reference qualities for normalization have been calculated yet. in this special case the ReferenceQualityAnalyzer will do the normalization
-        referenceQualities = new double[problems.Count];
-        for (int i = 0; i < referenceQualities.Length; i++) {
-          referenceQualities[i] = 1;
-        }
-      } else {
-        referenceQualities = ProblemQualityReferencesParameter.ActualValue.ToArray();
-      }
-      return referenceQualities;
-    }
-
-    /// <summary>
-    /// Executes an algorithm 
-    /// </summary>
-    private static RunCollection ExecuteAlgorithm(ParameterConfigurationTree parameterConfiguration, IAlgorithm algorithm, IItemList<IProblem> problems, int repetitions, int currentGeneration) {
-      IAlgorithm algorithmClone = (IAlgorithm)algorithm.Clone();
-      var parameterNames = parameterConfiguration.GetOptimizedParameterNames();
-      var resultNames = new List<string> { "BestQuality", "Execution Time" };
-
-      // set parameters
-      parameterConfiguration.Parameterize(algorithmClone);
-      algorithmClone.StoreAlgorithmInEachRun = false;
-
-      if (algorithmClone is EngineAlgorithm) {
-        ((EngineAlgorithm)algorithmClone).Engine = new SequentialEngine.SequentialEngine();
-      }
-      algorithmClone.Prepare(true);
-
-      foreach (IProblem problem in problems) {
-        algorithmClone.Problem = (IProblem)problem.Clone();
-
-        for (int i = 0; i < repetitions; i++) {
-          algorithmClone.Prepare();
-
-          AlgorithmExecutor executor = new AlgorithmExecutor(algorithmClone);
-          executor.StartSync();
-
-          if (algorithmClone.ExecutionState == ExecutionState.Paused) {
-            // the parameter settings were invalid. 
-            // (1) set penalty for this solution. 
-            //     it's difficult to create penalty values for BestQuality and ExecutionTime. Maybe ReferenceQuality * X (but what about ExecutionTime?)
-            //     therefore use repair instead.
-            
-            // (2) repair and retry
-            return null;
-          }
-          int problemIndex = problems.IndexOf(problem) + 1;
-          IRun run = algorithmClone.Runs.Last();
-          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));
-          int runCountOfThisProblem = algorithmClone.Runs.Where(x => ((IntValue)x.Results["Meta.ProblemIndex"]).Value == problemIndex).Count();
-          run.Name = string.Format("{0} Problem {1} Run {2}", parameterConfiguration.ParameterInfoString, problemIndex, runCountOfThisProblem);
-        }
-      }
-      algorithmClone.Prepare();
-      return algorithmClone.Runs;
-    }
-  }
-}
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/HeuristicLab.Problems.MetaOptimization-3.3.csproj
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/HeuristicLab.Problems.MetaOptimization-3.3.csproj	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/HeuristicLab.Problems.MetaOptimization-3.3.csproj	(revision 5653)
@@ -143,4 +143,10 @@
     <Compile Include="Analyzers\PMOPopulationDiversityAnalyzer.cs" />
     <Compile Include="ConstrainedTypeValue.cs" />
+    <Compile Include="Encoding\ValueConfigurations\RangeValueConfiguration.cs" />
+    <Compile Include="Encoding\ValueConfigurations\ParameterizedValueConfiguration.cs" />
+    <Compile Include="Evaluators\AlgorithmEvaluator.cs" />
+    <Compile Include="Evaluators\AlgorithmRunsAnalyzer.cs" />
+    <Compile Include="Evaluators\AlgorithmSubScopesCreator.cs" />
+    <Compile Include="Evaluators\PMOEvaluator.cs" />
     <Compile Include="MetaOptimizationUtil.cs" />
     <Compile Include="Operators\Crossovers\MultiIntValueCrossover.cs" />
@@ -167,5 +173,5 @@
     <Compile Include="Encoding\ValueConfigurations\ValueConfiguration.cs" />
     <Compile Include="Encoding\ValueConfigurations\CheckedValueConfigurationCollection.cs" />
-    <Compile Include="Evaluators\AlgorithmExecutor.cs" />
+    <Compile Include="AlgorithmExecutor.cs" />
     <Compile Include="Interfaces\IParameterConfigurationCrossover.cs" />
     <Compile Include="Interfaces\ICheckedValueConfigurationCollection.cs" />
@@ -185,5 +191,4 @@
     <Compile Include="Interfaces\IParameterConfigurationOperator.cs" />
     <Compile Include="Interfaces\IRange.cs" />
-    <Compile Include="Evaluators\ParameterConfigurationEvaluator.cs" />
     <Compile Include="Interfaces\IParameterConfigurationEvaluator.cs" />
     <Compile Include="Interfaces\IParameterConfiguration.cs" />
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IOptimizable.cs	(revision 5653)
@@ -1,8 +1,5 @@
 ﻿using System;
 using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 using HeuristicLab.Core;
-using HeuristicLab.Common;
 
 namespace HeuristicLab.Problems.MetaOptimization {
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IValueConfiguration.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IValueConfiguration.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Interfaces/IValueConfiguration.cs	(revision 5653)
@@ -1,11 +1,7 @@
 ﻿using System;
 using HeuristicLab.Core;
-using HeuristicLab.Data;
-using System.Collections.Generic;
 
 namespace HeuristicLab.Problems.MetaOptimization {
   public interface IValueConfiguration : IOptimizable, IItem {
-    IItemCollection<IParameterConfiguration> ParameterConfigurations { get; }
-    IRange RangeConstraint { get; }
     int Number { get; set; } // if larger than 0 it will be visible in the name. this can be used when multiple ValueConfiguration with the same name exist in a list
     string NumberedName { get; }
@@ -13,5 +9,5 @@
     event EventHandler ValueChanged;
     
-    void Parameterize(IParameterizedItem item);
+    //void Parameterize(IParameterizedItem item);
   }
 }
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 5576)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 5653)
@@ -137,5 +137,5 @@
       Maximization = new BoolValue(false);
       SolutionCreator = new RandomParameterConfigurationCreator();
-      Evaluator = new ParameterConfigurationEvaluator();
+      Evaluator = new PMOEvaluator();
 
       InitializeOperators();
@@ -186,5 +186,5 @@
     }
     private void ParameterizeEvaluator() {
-      ((ParameterConfigurationEvaluator)Evaluator).ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
+      ((PMOEvaluator)Evaluator).ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
     }
     private void ParameterizeAnalyzer() {
@@ -246,7 +246,8 @@
       IAlgorithm instance = (IAlgorithm)Activator.CreateInstance(AlgorithmType.Value);
       this.ProblemType.ValidTypes = ApplicationManager.Manager.GetTypes(instance.ProblemType, true).ToList();
-      this.ProblemType.Value = this.ProblemType.ValidTypes.Where(t => t != typeof(MetaOptimizationProblem)).FirstOrDefault();
+      this.ProblemType.Value = this.ProblemType.ValidTypes.SingleOrDefault(t => t == typeof(SingleObjectiveTestFunctionProblem)) ?? this.ProblemType.ValidTypes.Where(t => t != typeof(MetaOptimizationProblem)).FirstOrDefault();
       if (ProblemType.Value != null) {
         ParameterConfigurationTreeParameter.ActualValue = new ParameterConfigurationTree(CreateAlgorithm(AlgorithmType.Value, ProblemType.Value));
+        Problems.Add((IProblem)Activator.CreateInstance(this.ProblemType.Value));
       } else {
         ParameterConfigurationTreeParameter.ActualValue = null;
Index: branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Operators/Crossovers/MultiIntValueCrossover.cs
===================================================================
--- branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Operators/Crossovers/MultiIntValueCrossover.cs	(revision 5653)
+++ branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Operators/Crossovers/MultiIntValueCrossover.cs	(revision 5653)
@@ -0,0 +1,47 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Optimization;
+using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Data;
+using HeuristicLab.Core;
+using HeuristicLab.Common;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+
+namespace HeuristicLab.Problems.MetaOptimization.Operators.Crossovers {
+  [Item("MultiIntValueCrossover", "Randomly selects and applies one of its crossovers every time it is called.")]
+  [StorableClass]
+  public class MultiIntValueCrossover : StochasticMultiBranch<IIntValueCrossover>, IIntValueCrossover, IStochasticOperator {
+    public override bool CanChangeName {
+      get { return false; }
+    }
+    protected override bool CreateChildOperation {
+      get { return true; }
+    }
+
+    [StorableConstructor]
+    protected MultiIntValueCrossover(bool deserializing) : base(deserializing) { }
+    public MultiIntValueCrossover() {
+      foreach (Type type in ApplicationManager.Manager.GetTypes(typeof(IIntValueCrossover)).OrderBy(op => op.Name)) {
+        if (!typeof(MultiOperator<IIntValueCrossover>).IsAssignableFrom(type))
+          Operators.Add((IIntValueCrossover)Activator.CreateInstance(type), true);
+      }
+    }
+    protected MultiIntValueCrossover(MultiIntValueCrossover original, Cloner cloner) : base(original, cloner) {
+    }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new MultiIntValueCrossover(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      if (Operators.Count == 0) throw new InvalidOperationException(Name + ": Please add at least one permutation crossover to choose from.");
+      return base.Apply();
+    }
+
+    public void Apply(IRandom random, IntValue value, IntValue other, IntValueRange range) {
+
+    }
+  }
+}
