Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/CrowdedTournamentSelector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/CrowdedTournamentSelector.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/CrowdedTournamentSelector.cs	(revision 4045)
@@ -33,5 +33,16 @@
 namespace HeuristicLab.Algorithms.NSGA2 {
   public class CrowdedTournamentSelector : Selector, IMultiObjectiveSelector, IStochasticOperator {
-
+    public ILookupParameter<BoolArray> MaximizationParameter {
+      get { return (ILookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+    public IValueLookupParameter<IntValue> NumberOfSelectedSubScopesParameter {
+      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfSelectedSubScopes"]; }
+    }
+    public IValueParameter<BoolValue> CopySelectedParameter {
+      get { return (IValueParameter<BoolValue>)Parameters["CopySelected"]; }
+    }
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
     public ILookupParameter<ItemArray<DoubleArray>> QualitiesParameter {
       get { return (ILookupParameter<ItemArray<DoubleArray>>)Parameters["Qualities"]; }
@@ -43,10 +54,4 @@
       get { return (IScopeTreeLookupParameter<DoubleValue>)Parameters["CrowdingDistance"]; }
     }
-    public IValueParameter<BoolValue> CopySelectedParameter {
-      get { return (IValueParameter<BoolValue>)Parameters["CopySelected"]; }
-    }
-    public ILookupParameter<IRandom> RandomParameter {
-      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
-    }
     public IValueLookupParameter<IntValue> GroupSizeParameter {
       get { return (IValueLookupParameter<IntValue>)Parameters["GroupSize"]; }
@@ -56,8 +61,4 @@
       get { return CopySelectedParameter.Value; }
       set { CopySelectedParameter.Value = value; }
-    }
-
-    public IValueLookupParameter<IntValue> NumberOfSelectedSubScopesParameter {
-      get { return (IValueLookupParameter<IntValue>)Parameters["NumberOfSelectedSubScopes"]; }
     }
 
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/DefaultCrossover.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/DefaultCrossover.cs	(revision 4045)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/DefaultCrossover.cs	(revision 4045)
@@ -0,0 +1,56 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Core;
+using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
+using HeuristicLab.Optimization;
+using HeuristicLab.Parameters;
+
+namespace HeuristicLab.Algorithms.NSGA2 {
+  [Item("DefaultCrossover", "This operator creates a parent by copying a single individual.")]
+  [StorableClass]
+  public class DefaultCrossover : SingleSuccessorOperator, ICrossover, IStochasticOperator {
+    public ILookupParameter<IRandom> RandomParameter {
+      get { return (ILookupParameter<IRandom>)Parameters["Random"]; }
+    }
+
+    public DefaultCrossover()
+      : base() {
+      Parameters.Add(new LookupParameter<IRandom>("Random", "The random number generator."));
+    }
+
+    public override IOperation Apply() {
+      IScope scope = ExecutionContext.Scope;
+      int index = RandomParameter.ActualValue.Next(scope.SubScopes.Count);
+      IScope child = scope.SubScopes[index];
+
+      foreach (IVariable var in child.Variables)
+        scope.Variables.Add((IVariable)var.Clone());
+
+      return base.Apply();
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/FastNonDominatedSort.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/FastNonDominatedSort.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/FastNonDominatedSort.cs	(revision 4045)
@@ -39,6 +39,6 @@
     private enum DominationResult { Dominates, IsDominated, IsNonDominated };
 
-    public IValueLookupParameter<BoolArray> MaximizationsParameter {
-      get { return (IValueLookupParameter<BoolArray>)Parameters["Maximizations"]; }
+    public IValueLookupParameter<BoolArray> MaximizationParameter {
+      get { return (IValueLookupParameter<BoolArray>)Parameters["Maximization"]; }
     }
 
@@ -52,5 +52,5 @@
 
     public FastNonDominatedSort() {
-      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximizations", "Whether each objective is maximization or minimization."));
+      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximization", "Whether each objective is maximization or minimization."));
       Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The qualities of a solution.", 1));
       Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of a solution.", 1));
@@ -58,5 +58,5 @@
 
     public override IOperation Apply() {
-      BoolArray maximizations = MaximizationsParameter.ActualValue;
+      BoolArray maximization = MaximizationParameter.ActualValue;
       ItemArray<DoubleArray> qualities = QualitiesParameter.ActualValue;
       if (qualities == null) throw new InvalidOperationException(Name + ": No qualities found.");
@@ -74,5 +74,5 @@
         dominatedScopes[p] = new List<int>();
         for (int qI = pI + 1; qI < populationSize; qI++) {
-          DominationResult test = Dominates(qualities[pI], qualities[qI], maximizations);
+          DominationResult test = Dominates(qualities[pI], qualities[qI], maximization);
           if (test == DominationResult.Dominates) {
             dominatedScopes[p].Add(qI);
@@ -137,12 +137,4 @@
     }
 
-    /*private bool Dominates(DoubleArray left, DoubleArray right, BoolArray maximizations) {
-      for (int i = 0; i < left.Length; i++) {
-        if (IsDominated(left[i], right[i], maximizations[i]))
-          return false;
-      }
-      return true;
-    }*/
-
     private bool IsDominated(double left, double right, bool maximization) {
       return maximization && left < right
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/HeuristicLab.Algorithms.NSGA2-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/HeuristicLab.Algorithms.NSGA2-3.3.csproj	(revision 4044)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/HeuristicLab.Algorithms.NSGA2-3.3.csproj	(revision 4045)
@@ -79,4 +79,5 @@
     <Compile Include="CrowdedTournamentSelector.cs" />
     <Compile Include="CrowdingDistanceAssignment.cs" />
+    <Compile Include="DefaultCrossover.cs" />
     <Compile Include="FastNonDominatedSort.cs" />
     <Compile Include="HeuristicLabAlgorithmsNSGA2Plugin.cs" />
@@ -84,4 +85,5 @@
     <Compile Include="NSGA2MainLoop.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="RankAndCrowdingSorter.cs" />
     <None Include="Properties\AssemblyInfo.frame" />
   </ItemGroup>
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2.cs	(revision 4045)
@@ -32,4 +32,6 @@
 using HeuristicLab.Optimization.Operators;
 using HeuristicLab.PluginInfrastructure;
+using HeuristicLab.Selection;
+using HeuristicLab.Operators;
 
 namespace HeuristicLab.Algorithms.NSGA2 {
@@ -131,6 +133,9 @@
       get { return (SolutionsCreator)RandomCreator.Successor; }
     }
+    private RankAndCrowdingSorter RankAndCrowdingSorter {
+      get { return (RankAndCrowdingSorter)SolutionsCreator.Successor; }
+    }
     private NSGA2MainLoop MainLoop {
-      get { return (NSGA2MainLoop)SolutionsCreator.Successor; }
+      get { return (NSGA2MainLoop)RankAndCrowdingSorter.Successor; }
     }
     #endregion
@@ -143,5 +148,5 @@
       Parameters.Add(new ValueParameter<IntValue>("PopulationSize", "The size of the population of solutions.", new IntValue(100)));
       Parameters.Add(new ConstrainedValueParameter<ISelector>("Selector", "The operator used to select solutions for reproduction."));
-      Parameters.Add(new ValueParameter<PercentValue>("CrossoverProbability", "The probability that the crossover operator is applied on two parents.", new PercentValue(0.05)));
+      Parameters.Add(new ValueParameter<PercentValue>("CrossoverProbability", "The probability that the crossover operator is applied on two parents.", new PercentValue(0.9)));
       Parameters.Add(new ConstrainedValueParameter<ICrossover>("Crossover", "The operator used to cross solutions."));
       Parameters.Add(new ValueParameter<PercentValue>("MutationProbability", "The probability that the mutation operator is applied on a solution.", new PercentValue(0.05)));
@@ -152,4 +157,5 @@
       RandomCreator randomCreator = new RandomCreator();
       SolutionsCreator solutionsCreator = new SolutionsCreator();
+      RankAndCrowdingSorter rankAndCrowdingSorter = new RankAndCrowdingSorter();
       NSGA2MainLoop mainLoop = new NSGA2MainLoop();
       OperatorGraph.InitialOperator = randomCreator;
@@ -163,6 +169,11 @@
 
       solutionsCreator.NumberOfSolutionsParameter.ActualName = PopulationSizeParameter.Name;
-      solutionsCreator.Successor = mainLoop;
-
+      solutionsCreator.Successor = rankAndCrowdingSorter;
+
+      rankAndCrowdingSorter.CrowdingDistanceParameter.ActualName = "CrowdingDistance";
+      rankAndCrowdingSorter.RankParameter.ActualName = "Rank";
+      rankAndCrowdingSorter.Successor = mainLoop;
+
+      mainLoop.PopulationSizeParameter.ActualName = PopulationSizeParameter.Name;
       mainLoop.SelectorParameter.ActualName = SelectorParameter.Name;
       mainLoop.CrossoverParameter.ActualName = CrossoverParameter.Name;
@@ -175,10 +186,10 @@
       mainLoop.ResultsParameter.ActualName = "Results";
 
-      foreach (ISelector selector in ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is IMultiObjectiveSelector)).OrderBy(x => x.Name))
+      foreach (ISelector selector in ApplicationManager.Manager.GetInstances<ISelector>().Where(x => !(x is ISingleObjectiveSelector)).OrderBy(x => x.Name))
         SelectorParameter.ValidValues.Add(selector);
-      ISelector proportionalSelector = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("ProportionalSelector"));
-      if (proportionalSelector != null) SelectorParameter.Value = proportionalSelector;
-      
-      // TODO: parameterize selectors
+      ISelector tournamentSelector = SelectorParameter.ValidValues.FirstOrDefault(x => x.GetType().Name.Equals("CrowdedTournamentSelector"));
+      if (tournamentSelector != null) SelectorParameter.Value = tournamentSelector;
+
+      ParameterizeSelectors();
 
       AttachEventHandlers();
@@ -193,21 +204,38 @@
     #region Events
     protected override void OnProblemChanged() {
-      // parameterize pretty much everything
+      ParameterizeStochasticOperator(Problem.SolutionCreator);
+      ParameterizeStochasticOperator(Problem.Evaluator);
+      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
+      ParameterizeSolutionsCreator();
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+      ParameterizeAnalyzers();
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+      UpdateAnalyzers();
+      Problem.Evaluator.QualitiesParameter.ActualNameChanged += new EventHandler(Evaluator_QualitiesParameter_ActualNameChanged);
       base.OnProblemChanged();
     }
     protected override void Problem_SolutionCreatorChanged(object sender, EventArgs e) {
-      // parameterize SolutionCreator
+      ParameterizeStochasticOperator(Problem.SolutionCreator);
+      ParameterizeSolutionsCreator();
       base.Problem_SolutionCreatorChanged(sender, e);
     }
     protected override void Problem_EvaluatorChanged(object sender, EventArgs e) {
-      // parameterize StochasticOperators
-      // parameterize SolutionsCreator
-      // parameterize MainLoop
-      // parameterize Selectors
-      // parameterize Analyzers
+      ParameterizeStochasticOperator(Problem.Evaluator);
+      ParameterizeSolutionsCreator();
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+      ParameterizeAnalyzers();
       Problem.Evaluator.QualitiesParameter.ActualNameChanged += new EventHandler(Evaluator_QualitiesParameter_ActualNameChanged);
       base.Problem_EvaluatorChanged(sender, e);
     }
     protected override void Problem_OperatorsChanged(object sender, EventArgs e) {
+      foreach (IOperator op in Problem.Operators) ParameterizeStochasticOperator(op);
+      ParameterizeIterationBasedOperators();
+      UpdateCrossovers();
+      UpdateMutators();
+      UpdateAnalyzers();
       base.Problem_OperatorsChanged(sender, e);
     }
@@ -215,17 +243,15 @@
       base.Problem_Reset(sender, e);
     }
-
     private void PopulationSizeParameter_ValueChanged(object sender, EventArgs e) {
       PopulationSize.ValueChanged += new EventHandler(PopulationSize_ValueChanged);
-      // parameterize Selectors
+      ParameterizeSelectors();
     }
     private void PopulationSize_ValueChanged(object sender, EventArgs e) {
-      // parameterize Selectors
-    }
-
+      ParameterizeSelectors();
+    }
     private void Evaluator_QualitiesParameter_ActualNameChanged(object sender, EventArgs e) {
-      // parameterize Analyzers
-      // parameterize MainLoop
-      // parameterize Selectors
+      ParameterizeMainLoop();
+      ParameterizeSelectors();
+      ParameterizeAnalyzers();
     }
     #endregion
@@ -240,4 +266,71 @@
       }
     }
+    private void ParameterizeSolutionsCreator() {
+      SolutionsCreator.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      SolutionsCreator.SolutionCreatorParameter.ActualName = Problem.SolutionCreatorParameter.Name;
+    }
+    private void ParameterizeMainLoop() {
+      MainLoop.EvaluatorParameter.ActualName = Problem.EvaluatorParameter.Name;
+      MainLoop.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+      MainLoop.QualitiesParameter.ActualName = Problem.Evaluator.QualitiesParameter.ActualName;
+    }
+    private void ParameterizeStochasticOperator(IOperator op) {
+      if (op is IStochasticOperator)
+        ((IStochasticOperator)op).RandomParameter.ActualName = RandomCreator.RandomParameter.ActualName;
+    }
+    private void ParameterizeSelectors() {
+      foreach (ISelector selector in SelectorParameter.ValidValues) {
+        selector.CopySelected = new BoolValue(true);
+        selector.NumberOfSelectedSubScopesParameter.Value = new IntValue(2 * PopulationSizeParameter.Value.Value);
+        ParameterizeStochasticOperator(selector);
+      }
+      if (Problem != null) {
+        foreach (IMultiObjectiveSelector selector in SelectorParameter.ValidValues.OfType<IMultiObjectiveSelector>()) {
+          selector.MaximizationParameter.ActualName = Problem.MaximizationParameter.Name;
+          selector.QualitiesParameter.ActualName = Problem.Evaluator.QualitiesParameter.ActualName;
+        }
+      }
+    }
+    private void ParameterizeAnalyzers() {
+      // TODO: Parameterize Analyzers
+    }
+    private void ParameterizeIterationBasedOperators() {
+      if (Problem != null) {
+        foreach (IIterationBasedOperator op in Problem.Operators.OfType<IIterationBasedOperator>()) {
+          op.IterationsParameter.ActualName = "Generations";
+          op.MaximumIterationsParameter.ActualName = "MaximumGenerations";
+        }
+      }
+    }
+    private void UpdateCrossovers() {
+      ICrossover oldCrossover = CrossoverParameter.Value;
+      CrossoverParameter.ValidValues.Clear();
+      foreach (ICrossover crossover in Problem.Operators.OfType<ICrossover>().OrderBy(x => x.Name))
+        CrossoverParameter.ValidValues.Add(crossover);
+      if (oldCrossover != null) {
+        ICrossover crossover = CrossoverParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldCrossover.GetType());
+        if (crossover != null) CrossoverParameter.Value = crossover;
+      }
+    }
+    private void UpdateMutators() {
+      IManipulator oldMutator = MutatorParameter.Value;
+      MutatorParameter.ValidValues.Clear();
+      foreach (IManipulator mutator in Problem.Operators.OfType<IManipulator>().OrderBy(x => x.Name))
+        MutatorParameter.ValidValues.Add(mutator);
+      if (oldMutator != null) {
+        IManipulator mutator = MutatorParameter.ValidValues.FirstOrDefault(x => x.GetType() == oldMutator.GetType());
+        if (mutator != null) MutatorParameter.Value = mutator;
+      }
+    }
+    private void UpdateAnalyzers() {
+      Analyzer.Operators.Clear();
+      if (Problem != null) {
+        foreach (IAnalyzer analyzer in Problem.Operators.OfType<IAnalyzer>()) {
+          foreach (IScopeTreeLookupParameter param in analyzer.Parameters.OfType<IScopeTreeLookupParameter>())
+            param.Depth = 1;
+          Analyzer.Operators.Add(analyzer);
+        }
+      }
+    }
     #endregion
   }
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2MainLoop.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2MainLoop.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/NSGA2MainLoop.cs	(revision 4045)
@@ -39,9 +39,12 @@
       get { return (ValueLookupParameter<IRandom>)Parameters["Random"]; }
     }
-    public ValueLookupParameter<BoolValue> MaximizationParameter {
-      get { return (ValueLookupParameter<BoolValue>)Parameters["Maximization"]; }
-    }
-    public ScopeTreeLookupParameter<DoubleValue> QualityParameter {
-      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["Quality"]; }
+    public ValueLookupParameter<BoolArray> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (ScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+    public ValueLookupParameter<IntValue> PopulationSizeParameter {
+      get { return (ValueLookupParameter<IntValue>)Parameters["PopulationSize"]; }
     }
     public ValueLookupParameter<IOperator> SelectorParameter {
@@ -84,6 +87,7 @@
       #region Create parameters
       Parameters.Add(new ValueLookupParameter<IRandom>("Random", "A pseudo random number generator."));
-      Parameters.Add(new ValueLookupParameter<BoolValue>("Maximization", "True if the problem is a maximization problem, otherwise false."));
-      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("Quality", "The value which represents the quality of a solution."));
+      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximization", "True if an objective should be maximized, or false if it should be minimized."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The vector of quality values."));
+      Parameters.Add(new ValueLookupParameter<IntValue>("PopulationSize", "The population size."));
       Parameters.Add(new ValueLookupParameter<IOperator>("Selector", "The operator used to select solutions for reproduction."));
       Parameters.Add(new ValueLookupParameter<PercentValue>("CrossoverProbability", "The probability that the crossover operator is applied on a solution."));
@@ -105,13 +109,15 @@
       ChildrenCreator childrenCreator = new ChildrenCreator();
       UniformSubScopesProcessor uniformSubScopesProcessor = new UniformSubScopesProcessor();
+      StochasticBranch crossoverStochasticBranch = new StochasticBranch();
       Placeholder crossover = new Placeholder();
-      StochasticBranch stochasticBranch = new StochasticBranch();
+      DefaultCrossover noCrossover = new DefaultCrossover();
+      StochasticBranch mutationStochasticBranch = new StochasticBranch();
       Placeholder mutator = new Placeholder();
       Placeholder evaluator = new Placeholder();
       SubScopesRemover subScopesRemover = new SubScopesRemover();
-      SubScopesProcessor subScopesProcessor2 = new SubScopesProcessor();
-      BestSelector bestSelector = new BestSelector();
+      MergingReducer mergingReducer = new MergingReducer();
+      RankAndCrowdingSorter rankAndCrowdingSorter = new RankAndCrowdingSorter();
+      LeftSelector leftSelector = new LeftSelector();
       RightReducer rightReducer = new RightReducer();
-      MergingReducer mergingReducer = new MergingReducer();
       IntCounter intCounter = new IntCounter();
       Comparator comparator = new Comparator();
@@ -123,32 +129,39 @@
 
       resultsCollector1.CollectedValues.Add(new LookupParameter<IntValue>("Generations"));
-      resultsCollector1.ResultsParameter.ActualName = "Results";
+      resultsCollector1.ResultsParameter.ActualName = ResultsParameter.Name;
 
       analyzer1.Name = "Analyzer";
-      analyzer1.OperatorParameter.ActualName = "Analyzer";
+      analyzer1.OperatorParameter.ActualName = AnalyzerParameter.Name;
 
       selector.Name = "Selector";
-      selector.OperatorParameter.ActualName = "Selector";
+      selector.OperatorParameter.ActualName = SelectorParameter.Name;
 
       childrenCreator.ParentsPerChild = new IntValue(2);
 
+      crossoverStochasticBranch.ProbabilityParameter.ActualName = CrossoverProbabilityParameter.Name;
+      crossoverStochasticBranch.RandomParameter.ActualName = RandomParameter.Name;
+
       crossover.Name = "Crossover";
-      crossover.OperatorParameter.ActualName = "Crossover";
-
-      stochasticBranch.ProbabilityParameter.ActualName = "MutationProbability";
-      stochasticBranch.RandomParameter.ActualName = "Random";
+      crossover.OperatorParameter.ActualName = CrossoverParameter.Name;
+
+      noCrossover.Name = "Clone parent";
+      noCrossover.RandomParameter.ActualName = RandomParameter.Name;
+
+      mutationStochasticBranch.ProbabilityParameter.ActualName = MutationProbabilityParameter.Name;
+      mutationStochasticBranch.RandomParameter.ActualName = RandomParameter.Name;
 
       mutator.Name = "Mutator";
-      mutator.OperatorParameter.ActualName = "Mutator";
+      mutator.OperatorParameter.ActualName = MutatorParameter.Name;
 
       evaluator.Name = "Evaluator";
-      evaluator.OperatorParameter.ActualName = "Evaluator";
+      evaluator.OperatorParameter.ActualName = EvaluatorParameter.Name;
 
       subScopesRemover.RemoveAllSubScopes = true;
 
-      bestSelector.CopySelected = new BoolValue(false);
-      bestSelector.MaximizationParameter.ActualName = "Maximization";
-      bestSelector.NumberOfSelectedSubScopesParameter.ActualName = "Elites";
-      bestSelector.QualityParameter.ActualName = "Quality";
+      rankAndCrowdingSorter.CrowdingDistanceParameter.ActualName = "CrowdingDistance";
+      rankAndCrowdingSorter.RankParameter.ActualName = "Rank";
+
+      leftSelector.CopySelected = new BoolValue(false);
+      leftSelector.NumberOfSelectedSubScopesParameter.ActualName = PopulationSizeParameter.Name;
 
       intCounter.Increment = new IntValue(1);
@@ -158,8 +171,8 @@
       comparator.LeftSideParameter.ActualName = "Generations";
       comparator.ResultParameter.ActualName = "Terminate";
-      comparator.RightSideParameter.ActualName = "MaximumGenerations";
+      comparator.RightSideParameter.ActualName = MaximumGenerationsParameter.Name;
 
       resultsCollector2.CollectedValues.Add(new LookupParameter<IntValue>("Generations"));
-      resultsCollector2.ResultsParameter.ActualName = "Results";
+      resultsCollector2.ResultsParameter.ActualName = ResultsParameter.Name;
 
       analyzer2.Name = "Analyzer";
@@ -177,21 +190,23 @@
       subScopesProcessor1.Operators.Add(new EmptyOperator());
       subScopesProcessor1.Operators.Add(childrenCreator);
-      subScopesProcessor1.Successor = subScopesProcessor2;
+      subScopesProcessor1.Successor = mergingReducer;
       childrenCreator.Successor = uniformSubScopesProcessor;
-      uniformSubScopesProcessor.Operator = crossover;
+      uniformSubScopesProcessor.Operator = crossoverStochasticBranch;
       uniformSubScopesProcessor.Successor = null;
-      crossover.Successor = stochasticBranch;
-      stochasticBranch.FirstBranch = mutator;
-      stochasticBranch.SecondBranch = null;
-      stochasticBranch.Successor = evaluator;
+      crossoverStochasticBranch.FirstBranch = crossover;
+      crossoverStochasticBranch.SecondBranch = noCrossover;
+      crossoverStochasticBranch.Successor = mutationStochasticBranch;
+      crossover.Successor = null;
+      noCrossover.Successor = null;
+      mutationStochasticBranch.FirstBranch = mutator;
+      mutationStochasticBranch.SecondBranch = null;
+      mutationStochasticBranch.Successor = evaluator;
       mutator.Successor = null;
       evaluator.Successor = subScopesRemover;
       subScopesRemover.Successor = null;
-      subScopesProcessor2.Operators.Add(bestSelector);
-      subScopesProcessor2.Operators.Add(new EmptyOperator());
-      subScopesProcessor2.Successor = mergingReducer;
-      bestSelector.Successor = rightReducer;
-      rightReducer.Successor = null;
-      mergingReducer.Successor = intCounter;
+      mergingReducer.Successor = rankAndCrowdingSorter;
+      rankAndCrowdingSorter.Successor = leftSelector;
+      leftSelector.Successor = rightReducer;
+      rightReducer.Successor = intCounter;
       intCounter.Successor = comparator;
       comparator.Successor = resultsCollector2;
@@ -203,10 +218,4 @@
       #endregion
     }
-
-    public override IOperation Apply() {
-      if (CrossoverParameter.ActualValue == null)
-        return null;
-      return base.Apply();
-    }
   }
 }
Index: /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/RankAndCrowdingSorter.cs
===================================================================
--- /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/RankAndCrowdingSorter.cs	(revision 4045)
+++ /trunk/sources/HeuristicLab.Algorithms.NSGA2/3.3/RankAndCrowdingSorter.cs	(revision 4045)
@@ -0,0 +1,79 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Operators;
+using HeuristicLab.Core;
+using HeuristicLab.Selection;
+using HeuristicLab.Parameters;
+using HeuristicLab.Data;
+
+namespace HeuristicLab.Algorithms.NSGA2 {
+  public class RankAndCrowdingSorter : AlgorithmOperator {
+    public ValueLookupParameter<BoolArray> MaximizationParameter {
+      get { return (ValueLookupParameter<BoolArray>)Parameters["Maximization"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleArray> QualitiesParameter {
+      get { return (ScopeTreeLookupParameter<DoubleArray>)Parameters["Qualities"]; }
+    }
+    public ScopeTreeLookupParameter<IntValue> RankParameter {
+      get { return (ScopeTreeLookupParameter<IntValue>)Parameters["Rank"]; }
+    }
+    public ScopeTreeLookupParameter<DoubleValue> CrowdingDistanceParameter {
+      get { return (ScopeTreeLookupParameter<DoubleValue>)Parameters["CrowdingDistance"]; }
+    }
+
+    public RankAndCrowdingSorter()
+      : base() {
+      Parameters.Add(new ValueLookupParameter<BoolArray>("Maximization", "For each objective a value that is true if that objective should be maximized, or false if it should be minimized."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleArray>("Qualities", "The vector of quality values."));
+      Parameters.Add(new ScopeTreeLookupParameter<IntValue>("Rank", "The rank of a solution (to which front it belongs)."));
+      Parameters.Add(new ScopeTreeLookupParameter<DoubleValue>("CrowdingDistance", "The crowding distance of a solution in a population."));
+
+      FastNonDominatedSort fastNonDominatedSort = new FastNonDominatedSort();
+      UniformSubScopesProcessor subScopesProcessor = new UniformSubScopesProcessor();
+      CrowdingDistanceAssignment crowdingDistanceAssignment = new CrowdingDistanceAssignment();
+      CrowdedComparisonSorter crowdedComparisonSorter = new CrowdedComparisonSorter();
+      MergingReducer mergingReducer = new MergingReducer();
+
+      fastNonDominatedSort.MaximizationParameter.ActualName = MaximizationParameter.Name;
+      fastNonDominatedSort.QualitiesParameter.ActualName = QualitiesParameter.Name;
+      fastNonDominatedSort.RankParameter.ActualName = RankParameter.Name;
+
+      crowdingDistanceAssignment.CrowdingDistanceParameter.ActualName = CrowdingDistanceParameter.Name;
+      crowdingDistanceAssignment.QualitiesParameter.ActualName = QualitiesParameter.Name;
+
+      crowdedComparisonSorter.CrowdingDistanceParameter.ActualName = CrowdingDistanceParameter.Name;
+      crowdedComparisonSorter.RankParameter.ActualName = RankParameter.Name;
+
+      OperatorGraph.InitialOperator = fastNonDominatedSort;
+      fastNonDominatedSort.Successor = subScopesProcessor;
+      subScopesProcessor.Operator = crowdingDistanceAssignment;
+      crowdingDistanceAssignment.Successor = crowdedComparisonSorter;
+      crowdedComparisonSorter.Successor = null;
+      subScopesProcessor.Successor = mergingReducer;
+      mergingReducer.Successor = null;
+    }
+  }
+}
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 4044)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/HeuristicLab.Encodings.PermutationEncoding-3.3.csproj	(revision 4045)
@@ -112,4 +112,5 @@
     <Compile Include="Moves\PermutationMoveAttribute.cs" />
     <Compile Include="Moves\ThreeIndexMove.cs" />
+    <Compile Include="Moves\ThreeOpt\StochasticSingleInsertionMoveGenerator.cs" />
     <Compile Include="Moves\ThreeOpt\TranslocationMoveAbsoluteAttribute.cs" />
     <Compile Include="Moves\ThreeOpt\ExhaustiveInsertionMoveGenerator.cs">
Index: /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs
===================================================================
--- /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Encodings.PermutationEncoding/3.3/Moves/ThreeOpt/TranslocationMoveSoftTabuCriterion.cs	(revision 4045)
@@ -137,13 +137,10 @@
                 if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T || attribute.Edge1Source == E1T && attribute.Edge1Target == E3S
                   || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T || attribute.Edge1Source == E3T && attribute.Edge1Target == E2S
-                  || attribute.Edge1Source == E1S && attribute.Edge1Target == E2T || attribute.Edge1Source == E2T && attribute.Edge1Target == E1S
                   // if previously deleted Edge2Source-Target is readded
                   || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T || attribute.Edge2Source == E1T && attribute.Edge2Target == E3S
                   || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T || attribute.Edge2Source == E3T && attribute.Edge2Target == E2S
-                  || attribute.Edge2Source == E1S && attribute.Edge2Target == E2T || attribute.Edge2Source == E2T && attribute.Edge2Target == E1S
                   // if previously deleted Edge3Source-Target is readded
                   || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T || attribute.Edge3Source == E1T && attribute.Edge3Target == E3S
-                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T || attribute.Edge3Source == E3T && attribute.Edge3Target == E2S
-                  || attribute.Edge3Source == E1S && attribute.Edge3Target == E2T || attribute.Edge3Source == E2T && attribute.Edge3Target == E1S) {
+                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T || attribute.Edge3Source == E3T && attribute.Edge3Target == E2S) {
                   isTabu = true;
                   break;
@@ -152,13 +149,10 @@
                 if (attribute.Edge1Source == E3S && attribute.Edge1Target == E1T
                   || attribute.Edge1Source == E2S && attribute.Edge1Target == E3T
-                  || attribute.Edge1Source == E1S && attribute.Edge1Target == E2T
                   // if previously deleted Edge2Source-Target is readded
                   || attribute.Edge2Source == E3S && attribute.Edge2Target == E1T
                   || attribute.Edge2Source == E2S && attribute.Edge2Target == E3T
-                  || attribute.Edge2Source == E1S && attribute.Edge2Target == E2T
                   // if previously deleted Edge3Source-Target is readded
                   || attribute.Edge3Source == E3S && attribute.Edge3Target == E1T
-                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T
-                  || attribute.Edge3Source == E1S && attribute.Edge3Target == E2T) {
+                  || attribute.Edge3Source == E2S && attribute.Edge3Target == E3T) {
                   isTabu = true;
                   break;
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveProblem.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveProblem.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveProblem.cs	(revision 4045)
@@ -20,4 +20,6 @@
 #endregion
 
+using HeuristicLab.Core;
+
 namespace HeuristicLab.Optimization {
   /// <summary>
@@ -25,4 +27,5 @@
   /// </summary>
   public interface IMultiObjectiveProblem : IProblem {
+    IParameter MaximizationParameter { get; }
     new IMultiObjectiveEvaluator Evaluator { get; }
   }
Index: /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs
===================================================================
--- /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs	(revision 4044)
+++ /trunk/sources/HeuristicLab.Optimization/3.3/Interfaces/IMultiObjectiveSelector.cs	(revision 4045)
@@ -29,4 +29,5 @@
   /// </summary>
   public interface IMultiObjectiveSelector : ISelector {
+    ILookupParameter<BoolArray> MaximizationParameter { get; }
     ILookupParameter<ItemArray<DoubleArray>> QualitiesParameter { get; }
   }
