Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs	(revision 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.MetaOptimization.Test/Program.cs	(revision 5576)
@@ -48,8 +48,8 @@
     //private static int baseAlgorithmMaxGenerations = 1000;
 
-    private static int metaAlgorithmPopulationSize = 20;
-    private static int metaAlgorithmMaxGenerations = 20;
+    private static int metaAlgorithmPopulationSize = 5;
+    private static int metaAlgorithmMaxGenerations = 15;
     private static int metaProblemRepetitions = 2;
-    private static int baseAlgorithmMaxGenerations = 10;
+    private static int baseAlgorithmMaxGenerations = 5;
     private static double mutationProbability = 0.10;
 
@@ -638,17 +638,17 @@
         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, 0, 20, 1);
+      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);
       ConfigureMutationOperator(algorithmVc);
-      ConfigureElites(algorithmVc, 0, 30, 1);
+      //ConfigureElites(algorithmVc, 0, 30, 1);
       ConfigureSelectionOperator(algorithmVc, true);
       return algorithmVc;
@@ -855,5 +855,5 @@
                 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;
@@ -869,5 +869,5 @@
                     ((IntValue)run.Parameters["PopulationSize"]).Value.ToString(),
                     ((DoubleValue)run.Parameters["MutationProbability"]).Value.ToString("0.0000"),
-                    ((IntValue)run.Parameters["Elites"]).Value.ToString(),
+                    //((IntValue)run.Parameters["Elites"]).Value.ToString(),
                     Shorten(selector, 20),
                     Shorten(run.Parameters.ContainsKey("Mutator") ? run.Parameters["Mutator"].ToString() : "null", 40),
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/BestParameterConfigurationAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/BestParameterConfigurationAnalyzer.cs	(revision 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/BestParameterConfigurationAnalyzer.cs	(revision 5576)
@@ -97,10 +97,5 @@
       RunCollection rc = new RunCollection();
       foreach (ParameterConfigurationTree pt in parameterTrees.OrderBy(x => x.AverageQualityNormalized)) { // todo: respect Maximization:true/false
-        IRun run = new Run();
-        run.Name = string.Format("Individual {0} ({1})", i, pt.ParameterInfoString);
-        pt.CollectResultValues(run.Results);
-        pt.CollectParameterValues(run.Parameters);
-        MetaOptimizationUtil.ClearParameters(run, pt.GetOptimizedParameterNames());
-        rc.Add(run);
+        rc.Add(pt.ToRun(string.Format("Individual {0} ({1})", i, pt.ParameterInfoString)));
         i++;
       }
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs	(revision 5576)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOBestSolutionHistoryAnalyzer.cs	(revision 5576)
@@ -0,0 +1,79 @@
+﻿using System.Linq;
+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 System;
+using HeuristicLab.Analysis;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  /// <summary>
+  /// TODO 
+  /// </summary>
+  [Item("PMOBestSolutionHistoryAnalyzer", "")]
+  [StorableClass]
+  public sealed class PMOBestSolutionHistoryAnalyzer : SingleSuccessorOperator, IAnalyzer {
+
+    public ScopeTreeLookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ScopeTreeLookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public LookupParameter<ConstrainedItemList<IProblem>> ProblemsParameter {
+      get { return (LookupParameter<ConstrainedItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
+    }
+    public LookupParameter<IntValue> GenerationsParameter {
+      get { return (LookupParameter<IntValue>)Parameters["Generations"]; }
+    }
+
+    public PMOBestSolutionHistoryAnalyzer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", ""));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", ""));
+      Parameters.Add(new LookupParameter<ConstrainedItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName));
+      Parameters.Add(new LookupParameter<IntValue>("Generations", ""));
+    }
+
+    [StorableConstructor]
+    private PMOBestSolutionHistoryAnalyzer(bool deserializing) : base(deserializing) { }
+    private PMOBestSolutionHistoryAnalyzer(PMOBestSolutionHistoryAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PMOBestSolutionHistoryAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      ResultCollection results = ResultsParameter.ActualValue;
+      ItemArray<ParameterConfigurationTree> parameterTrees = ParameterConfigurationParameter.ActualValue;
+      int currentGeneration = GenerationsParameter.ActualValue.Value;
+      int idxBest = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index; // todo: respect Min/Max
+      ParameterConfigurationTree best = parameterTrees[idxBest];
+
+      string key = "BestSolutionHistory";
+      RunCollection bestSolutionHistory;
+      if (!results.ContainsKey(key)) {
+        bestSolutionHistory = new RunCollection();
+        results.Add(new Result(key, bestSolutionHistory));
+      } else {
+        bestSolutionHistory = results[key].Value as RunCollection;
+      }
+      if (bestSolutionHistory.Count == 0 || best.ParameterInfoString != ((StringValue)bestSolutionHistory.Last().Results["Meta.ParameterInfoString"]).Value) {
+        IRun run = best.ToRun(string.Format("{0}: {1}", currentGeneration, best.ParameterInfoString));
+        run.Results.Add("Meta.Generation", new IntValue(currentGeneration));
+        run.Results.Add("Meta.ParameterInfoString", new StringValue(best.ParameterInfoString));
+        bestSolutionHistory.Add(run);
+      }
+
+      return base.Apply();
+    }
+  }
+}
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOProblemQualitiesAnalyzer.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOProblemQualitiesAnalyzer.cs	(revision 5576)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Analyzers/PMOProblemQualitiesAnalyzer.cs	(revision 5576)
@@ -0,0 +1,102 @@
+﻿using System.Linq;
+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 System;
+using HeuristicLab.Analysis;
+
+namespace HeuristicLab.Problems.MetaOptimization {
+  /// <summary>
+  /// TODO 
+  /// </summary>
+  [Item("PMOProblemQualitiesAnalyzer", "")]
+  [StorableClass]
+  public sealed class PMOProblemQualitiesAnalyzer : SingleSuccessorOperator, IAnalyzer {
+
+    public ScopeTreeLookupParameter<ParameterConfigurationTree> ParameterConfigurationParameter {
+      get { return (ScopeTreeLookupParameter<ParameterConfigurationTree>)Parameters["ParameterConfigurationTree"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    }
+    public ValueLookupParameter<ResultCollection> ResultsParameter {
+      get { return (ValueLookupParameter<ResultCollection>)Parameters["Results"]; }
+    }
+    public LookupParameter<ConstrainedItemList<IProblem>> ProblemsParameter {
+      get { return (LookupParameter<ConstrainedItemList<IProblem>>)Parameters[MetaOptimizationProblem.ProblemsParameterName]; }
+    }
+
+    public PMOProblemQualitiesAnalyzer()
+      : base() {
+      Parameters.Add(new ScopeTreeLookupParameter<ParameterConfigurationTree>("ParameterConfigurationTree", ""));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", ""));
+      Parameters.Add(new ValueLookupParameter<ResultCollection>("Results", ""));
+      Parameters.Add(new LookupParameter<ConstrainedItemList<IProblem>>(MetaOptimizationProblem.ProblemsParameterName));
+    }
+
+    [StorableConstructor]
+    private PMOProblemQualitiesAnalyzer(bool deserializing) : base(deserializing) { }
+    private PMOProblemQualitiesAnalyzer(PMOProblemQualitiesAnalyzer original, Cloner cloner) : base(original, cloner) { }
+    public override IDeepCloneable Clone(Cloner cloner) {
+      return new PMOProblemQualitiesAnalyzer(this, cloner);
+    }
+
+    public override IOperation Apply() {
+      ItemArray<DoubleValue> qualities = QualityParameter.ActualValue;
+      ResultCollection results = ResultsParameter.ActualValue;
+      ItemArray<ParameterConfigurationTree> parameterTrees = ParameterConfigurationParameter.ActualValue;
+      int idxBest = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).First().index; // todo: respect Min/Max
+      int idxWorst = qualities.Select((x, index) => new { index, x.Value }).OrderBy(x => x.Value).Last().index;
+      
+      int problemCount = ProblemsParameter.ActualValue.Count;
+
+      double[][] problemQualities = GetProblemQualities(parameterTrees, problemCount);
+
+      for (int i = 0; i < problemCount; i++) {
+        DataTable problemQualitiesDataTable;
+        string resultKey = "Problem." + i;
+        if (!results.ContainsKey(resultKey)) {
+          problemQualitiesDataTable = new DataTable();
+          problemQualitiesDataTable.Name = resultKey + " Qualities";
+          results.Add(new Result(resultKey, problemQualitiesDataTable));
+        } else {
+          problemQualitiesDataTable = results[resultKey].Value as DataTable;
+        }
+
+        AddValue(problemQualitiesDataTable, parameterTrees[idxBest].AverageQualities[i], "BestQuality", "BestQuality");
+        AddValue(problemQualitiesDataTable, problemQualities[i].Average(), "AverageQuality", "BestQuality");
+        AddValue(problemQualitiesDataTable, parameterTrees[idxWorst].AverageQualities[i], "WorstQuality", "BestQuality"); 
+      }
+
+      return base.Apply();
+    }
+
+    private static double[][] GetProblemQualities(ItemArray<ParameterConfigurationTree> parameterTrees, int problemCount) {
+      double[][] problemQualities = new double[problemCount][];
+      for (int i = 0; i < problemCount; i++) {
+        problemQualities[i] = new double[parameterTrees.Length];
+        for (int j = 0; j < parameterTrees.Length; j++) {
+          problemQualities[i][j] = parameterTrees[j].AverageQualities[i];
+        }
+      }
+      return problemQualities;
+    }
+
+    private static void AddValue(DataTable table, double data, string name, string description) {
+      DataRow row;
+      table.Rows.TryGetValue(name, out row);
+      if (row == null) {
+        row = new DataRow(name, description);
+        row.Values.Add(data);
+        table.Rows.Add(row);
+      } else {
+        row.Values.Add(data);
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/ParameterConfigurationTree.cs	(revision 5576)
@@ -240,4 +240,17 @@
       return this.Name;
     }
+
+    public IRun ToRun() {
+      return ToRun(this.ParameterInfoString);
+    }
+
+    public IRun ToRun(string name) {
+      IRun run = new Run();
+      run.Name = name;
+      this.CollectResultValues(run.Results);
+      this.CollectParameterValues(run.Parameters);
+      MetaOptimizationUtil.ClearParameters(run, this.GetOptimizedParameterNames());
+      return run;
+    }
   }
 }
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs	(revision 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/Encoding/RangeConstraints/Range.cs	(revision 5576)
@@ -53,5 +53,5 @@
         if (stepSize != value) {
           if (stepSize != null) {
-            stepSize.ValueChanged -= new EventHandler(upperBound_ToStringChanged);
+            stepSize.ValueChanged -= new EventHandler(stepSize_ToStringChanged);
           }
           stepSize = value;
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 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/HeuristicLab.Problems.MetaOptimization-3.3.csproj	(revision 5576)
@@ -139,7 +139,10 @@
   <ItemGroup>
     <Compile Include="Analyzers\BestParameterConfigurationAnalyzer.cs" />
+    <Compile Include="Analyzers\PMOBestSolutionHistoryAnalyzer.cs" />
+    <Compile Include="Analyzers\PMOProblemQualitiesAnalyzer.cs" />
     <Compile Include="Analyzers\PMOPopulationDiversityAnalyzer.cs" />
     <Compile Include="ConstrainedTypeValue.cs" />
     <Compile Include="MetaOptimizationUtil.cs" />
+    <Compile Include="Operators\Crossovers\MultiIntValueCrossover.cs" />
     <Compile Include="TypeValue.cs" />
     <None Include="Properties\AssemblyInfo.cs.frame" />
Index: /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs
===================================================================
--- /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 5575)
+++ /branches/HeuristicLab.MetaOptimization/HeuristicLab.Problems.MetaOptimization/3.3/MetaOptimizationProblem.cs	(revision 5576)
@@ -109,5 +109,11 @@
     private PMOPopulationDiversityAnalyzer PMOPopulationDiversityAnalyzer {
       get { return Operators.OfType<PMOPopulationDiversityAnalyzer>().FirstOrDefault(); }
-    }    
+    }
+    private PMOProblemQualitiesAnalyzer PMOProblemQualitiesAnalyzer {
+      get { return Operators.OfType<PMOProblemQualitiesAnalyzer>().FirstOrDefault(); }
+    }
+    private PMOBestSolutionHistoryAnalyzer PMOBestSolutionHistoryAnalyzer {
+      get { return Operators.OfType<PMOBestSolutionHistoryAnalyzer>().FirstOrDefault(); }
+    }
     #endregion
 
@@ -174,4 +180,6 @@
       Operators.Add(new SolutionCacheAnalyzer());
       Operators.Add(new PMOPopulationDiversityAnalyzer());
+      Operators.Add(new PMOProblemQualitiesAnalyzer());
+      Operators.Add(new PMOBestSolutionHistoryAnalyzer());
     }
     private void ParameterizeSolutionCreator() {
@@ -193,4 +201,10 @@
         PMOPopulationDiversityAnalyzer.SolutionParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
         PMOPopulationDiversityAnalyzer.StoreHistoryParameter.Value.Value = true;
+      }
+      if (PMOProblemQualitiesAnalyzer != null) {
+        PMOProblemQualitiesAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
+      }
+      if (PMOBestSolutionHistoryAnalyzer != null) {
+        PMOBestSolutionHistoryAnalyzer.ParameterConfigurationParameter.ActualName = ((RandomParameterConfigurationCreator)SolutionCreator).ParameterConfigurationParameter.ActualName;
       }
     }
