Index: branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/AlgorithmBase.cs
===================================================================
--- branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/AlgorithmBase.cs	(revision 2331)
+++ branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/AlgorithmBase.cs	(revision 2335)
@@ -46,4 +46,34 @@
     }
 
+    public virtual int MaxGenerations {
+      get { return GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual int Elites {
+      get { return GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual int MaxTreeSize {
+      get { return GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual int MinTreeSize {
+      get { return GetVariableInjector().GetVariable("MinTreeSize").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("MinTreeSize").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual int MaxTreeHeight {
+      get { return GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data = value; }
+    }
+
+    public virtual int Parents {
+      get { return GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data; }
+      set { GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data = value; }
+    }
+
     public virtual bool SetSeedRandomly {
       get { return GetRandomInjector().GetVariable("SetSeedRandomly").GetValue<BoolData>().Data; }
@@ -57,30 +87,21 @@
 
     public virtual IOperator ProblemInjector {
-      get { return algorithm.SubOperators[1]; }
+      get { return GetInitializationOperator().SubOperators[0]; }
       set {
         value.Name = "ProblemInjector";
-        algorithm.RemoveSubOperator(1);
-        algorithm.AddSubOperator(value, 1);
+        IOperator init = GetInitializationOperator();
+        init.RemoveSubOperator(0);
+        init.AddSubOperator(value, 0);
       }
     }
 
-    public virtual int Elites {
-      get { return GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("Elites").GetValue<IntData>().Data = value; }
-    }
-
-    public virtual int MaxTreeSize {
-      get { return GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("MaxTreeSize").GetValue<IntData>().Data = value; }
-    }
-
-    public virtual int MaxTreeHeight {
-      get { return GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("MaxTreeHeight").GetValue<IntData>().Data = value; }
-    }
-
-    public virtual int Parents {
-      get { return GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("Parents").GetValue<IntData>().Data = value; }
+    public virtual IOperator FunctionLibraryInjector {
+      get { return GetInitializationOperator().SubOperators[1]; }
+      set {
+        value.Name = "FunctionLibraryInjector";
+        IOperator init = GetInitializationOperator();
+        init.RemoveSubOperator(1);
+        init.AddSubOperator(value, 1);
+      }
     }
 
@@ -102,5 +123,7 @@
       MutationRate = 0.15;
       PopulationSize = 1000;
+      MaxGenerations = 100;
       MaxTreeSize = 100;
+      MinTreeSize = 1;
       MaxTreeHeight = 10;
       Parents = 2000;
@@ -111,38 +134,25 @@
       algo.Name = "GP";
       SequentialProcessor seq = new SequentialProcessor();
-      IOperator problemInjector = CreateProblemInjector();
-
-      RandomInjector randomInjector = new RandomInjector();
-      randomInjector.Name = "Random Injector";
-
-      IOperator globalInjector = CreateGlobalInjector();
-      IOperator initialization = CreateInitialization();
-      IOperator funLibInjector = CreateFunctionLibraryInjector();
+      IOperator init = CreateInitializationOperator();
+      init.AddSubOperator(CreateProblemInjector());
+      init.AddSubOperator(CreateFunctionLibraryInjector());
+      seq.AddSubOperator(init);
+
+      IOperator initPopulation = CreateInitialPopulationGenerator();
+      initPopulation.AddSubOperator(CreateRandomSolutionGenerator());
+      initPopulation.AddSubOperator(CreateInitialPopulationEvaluator());
+      seq.AddSubOperator(initPopulation);
 
       IOperator mainLoop = CreateMainLoop();
-      mainLoop.Name = "Main loop";
-
-      IOperator treeCreator = CreateTreeCreator();
-
-      IOperator crossover = CreateCrossover();
-      IOperator manipulator = CreateManipulator();
-
-      IOperator selector = CreateSelector();
-      LeftReducer cleanUp = new LeftReducer();
-
-      seq.AddSubOperator(randomInjector);
-      seq.AddSubOperator(problemInjector);
-      seq.AddSubOperator(globalInjector);
-      seq.AddSubOperator(funLibInjector);
-      seq.AddSubOperator(initialization);
+      mainLoop.AddSubOperator(CreateSelectionOperator());
+      mainLoop.AddSubOperator(CreateCrossoverOperator());
+      mainLoop.AddSubOperator(CreateManipulationOperator());
+      mainLoop.AddSubOperator(CreateEvaluationOperator());
+      mainLoop.AddSubOperator(CreateTerminationCondition());
       seq.AddSubOperator(mainLoop);
-      seq.AddSubOperator(cleanUp);
-
-      initialization.AddSubOperator(treeCreator);
-
-      mainLoop.AddSubOperator(selector);
-      mainLoop.AddSubOperator(crossover);
-      mainLoop.AddSubOperator(manipulator);
-      mainLoop.AddSubOperator(evaluator);
+
+      IOperator postProcess = CreatePostProcessingOperator();
+      seq.AddSubOperator(postProcess);
+
       algo.OperatorGraph.AddOperator(seq);
       algo.OperatorGraph.InitialOperator = seq;
@@ -151,24 +161,38 @@
     }
 
-    protected internal virtual IOperator CreateProblemInjector() {
-      return new EmptyOperator();
-    }
-
-    protected virtual IOperator CreateSelector() {
-      return new EmptyOperator();
-    }
-
-    protected virtual IOperator CreateCrossover() {
-      return new StandardCrossOver();
-    }
-
-    protected internal abstract IOperator CreateTreeCreator();
-
-    protected internal abstract IOperator CreateFunctionLibraryInjector();
-
-    protected internal virtual IOperator CreateGlobalInjector() {
+    #region global init
+    protected virtual IOperator CreateInitializationOperator() {
+      CombinedOperator init = new CombinedOperator();
+      init.Name = "Initialization";
+      SequentialProcessor seq = new SequentialProcessor();
+      seq.AddSubOperator(CreateRandomInjector());
+      seq.AddSubOperator(CreateGlobalInjector());
+
+      OperatorExtractor probInjectorExtractor = new OperatorExtractor();
+      probInjectorExtractor.Name = "ProblemInjector";
+      probInjectorExtractor.GetVariableInfo("Operator").ActualName = "ProblemInjector";
+      seq.AddSubOperator(probInjectorExtractor);
+
+      OperatorExtractor funLibInjectorExtractor = new OperatorExtractor();
+      funLibInjectorExtractor.Name = "FunctionLibraryInjector";
+      funLibInjectorExtractor.GetVariableInfo("Operator").ActualName = "FunctionLibraryInjector";
+      seq.AddSubOperator(funLibInjectorExtractor);
+
+      init.OperatorGraph.AddOperator(seq);
+      init.OperatorGraph.InitialOperator = seq;
+      return init;
+    }
+
+    protected virtual IOperator CreateRandomInjector() {
+      RandomInjector randomInjector = new RandomInjector();
+      randomInjector.Name = "Random Injector";
+      return randomInjector;
+    }
+
+    protected virtual VariableInjector CreateGlobalInjector() {
       VariableInjector injector = new VariableInjector();
       injector.Name = "Global Injector";
       injector.AddVariable(new HeuristicLab.Core.Variable("Generations", new IntData(0)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("MaxGenerations", new IntData()));
       injector.AddVariable(new HeuristicLab.Core.Variable("MutationRate", new DoubleData()));
       injector.AddVariable(new HeuristicLab.Core.Variable("PopulationSize", new IntData()));
@@ -177,17 +201,25 @@
       injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new IntData()));
       injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new IntData()));
+      injector.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new IntData()));
       injector.AddVariable(new HeuristicLab.Core.Variable("EvaluatedSolutions", new IntData(0)));
       injector.AddVariable(new HeuristicLab.Core.Variable("TotalEvaluatedNodes", new DoubleData(0)));
       injector.AddVariable(new HeuristicLab.Core.Variable("Parents", new IntData()));
-      injector.AddVariable(new HeuristicLab.Core.Variable("UseEstimatedTargetValue", new BoolData()));
-      injector.AddVariable(new HeuristicLab.Core.Variable("PunishmentFactor", new DoubleData(10.0)));
       return injector;
     }
 
-    protected internal abstract IOperator CreateManipulator();
-
-    protected internal virtual IOperator CreateInitialization() {
-      CombinedOperator init = new CombinedOperator();
-      init.Name = "Initialization";
+
+    protected virtual IOperator CreateProblemInjector() {
+      return new EmptyOperator();
+    }
+
+    protected virtual IOperator CreateFunctionLibraryInjector() {
+      return new EmptyOperator();
+    }
+    #endregion
+
+    #region population init
+    private IOperator CreateInitialPopulationGenerator() {
+      CombinedOperator initPopulation = new CombinedOperator();
+      initPopulation.Name = "Init population";
       SequentialProcessor seq = new SequentialProcessor();
       SubScopesCreater subScopesCreater = new SubScopesCreater();
@@ -197,12 +229,9 @@
       OperatorExtractor treeCreater = new OperatorExtractor();
       treeCreater.Name = "Tree generator (extr.)";
-      treeCreater.GetVariableInfo("Operator").ActualName = "Tree generator";
+      treeCreater.GetVariableInfo("Operator").ActualName = "Solution generator";
+
       OperatorExtractor evaluator = new OperatorExtractor();
       evaluator.Name = "Evaluator (extr.)";
       evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
-      MeanSquaredErrorEvaluator validationEvaluator = new MeanSquaredErrorEvaluator();
-      validationEvaluator.GetVariableInfo("MSE").ActualName = "ValidationQuality";
-      validationEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
-      validationEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
       Counter evalCounter = new Counter();
       evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
@@ -218,43 +247,53 @@
       individualSeq.AddSubOperator(treeCreater);
       individualSeq.AddSubOperator(evaluator);
-      individualSeq.AddSubOperator(validationEvaluator);
       individualSeq.AddSubOperator(evalCounter);
 
-      init.OperatorGraph.AddOperator(seq);
-      init.OperatorGraph.InitialOperator = seq;
-      return init;
-    }
-
-    protected internal virtual IOperator CreateMainLoop() {
+      initPopulation.OperatorGraph.AddOperator(seq);
+      initPopulation.OperatorGraph.InitialOperator = seq;
+      return initPopulation;
+    }
+
+    protected virtual IOperator CreateRandomSolutionGenerator() {
+      ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
+      treeCreator.Name = "Solution generator";
+      return treeCreator;
+    }
+
+    protected virtual IOperator CreateInitialPopulationEvaluator() {
+      return new EmptyOperator();
+    }
+    #endregion
+
+    #region mainloop
+    protected virtual IOperator CreateMainLoop() {
       CombinedOperator main = new CombinedOperator();
+      main.Name = "Main";
       SequentialProcessor seq = new SequentialProcessor();
       IOperator childCreater = CreateChildCreater();
       IOperator replacement = CreateReplacement();
 
-      BestSolutionStorer solutionStorer = new BestSolutionStorer();
-      solutionStorer.GetVariableInfo("Quality").ActualName = "ValidationQuality";
-      solutionStorer.GetVariableInfo("BestSolution").ActualName = "BestValidationSolution";
-      solutionStorer.AddSubOperator(CreateBestSolutionProcessor());
-
       BestAverageWorstQualityCalculator qualityCalculator = new BestAverageWorstQualityCalculator();
-      BestAverageWorstQualityCalculator validationQualityCalculator = new BestAverageWorstQualityCalculator();
-      validationQualityCalculator.Name = "BestAverageWorstValidationQualityCalculator";
-      validationQualityCalculator.GetVariableInfo("Quality").ActualName = "ValidationQuality";
-      validationQualityCalculator.GetVariableInfo("BestQuality").ActualName = "BestValidationQuality";
-      validationQualityCalculator.GetVariableInfo("AverageQuality").ActualName = "AverageValidationQuality";
-      validationQualityCalculator.GetVariableInfo("WorstQuality").ActualName = "WorstValidationQuality";
       IOperator loggingOperator = CreateLoggingOperator();
       Counter counter = new Counter();
       counter.GetVariableInfo("Value").ActualName = "Generations";
-      IOperator loopCondition = CreateLoopCondition(seq);
+
+      OperatorExtractor terminationCriterionExtractor = new OperatorExtractor();
+      terminationCriterionExtractor.Name = "TerminationCondition (extr.)";
+      terminationCriterionExtractor.GetVariableInfo("Operator").ActualName = "TerminationCondition";
+
+      ConditionalBranch loop = new ConditionalBranch();
+      loop.Name = "Main loop";
+      loop.GetVariableInfo("Condition").ActualName = "TerminationCriterion";
+      loop.AddSubOperator(new EmptyOperator());
+      loop.AddSubOperator(seq);
 
       seq.AddSubOperator(childCreater);
       seq.AddSubOperator(replacement);
-      seq.AddSubOperator(solutionStorer);
       seq.AddSubOperator(qualityCalculator);
-      seq.AddSubOperator(validationQualityCalculator);
+      seq.AddSubOperator(CreateGenerationStepHook());
       seq.AddSubOperator(loggingOperator);
       seq.AddSubOperator(counter);
-      seq.AddSubOperator(loopCondition);
+      seq.AddSubOperator(terminationCriterionExtractor);
+      seq.AddSubOperator(loop);
 
       main.OperatorGraph.AddOperator(seq);
@@ -263,73 +302,5 @@
     }
 
-    protected internal virtual IOperator CreateLoggingOperator() {
-      return new EmptyOperator();
-    }
-
-    protected internal virtual IOperator CreateLoopCondition(IOperator loop) {
-      SequentialProcessor seq = new SequentialProcessor();
-      seq.Name = "Loop Condition";
-      LessThanComparator comparator = new LessThanComparator();
-      comparator.GetVariableInfo("LeftSide").ActualName = "Generations";
-      comparator.GetVariableInfo("RightSide").ActualName = "MaxGenerations";
-      comparator.GetVariableInfo("Result").ActualName = "GenerationsCondition";
-      ConditionalBranch cond = new ConditionalBranch();
-      cond.GetVariableInfo("Condition").ActualName = "GenerationsCondition";
-
-      seq.AddSubOperator(comparator);
-      seq.AddSubOperator(cond);
-
-      cond.AddSubOperator(loop);
-      return seq;
-    }
-
-    protected internal virtual IOperator CreateBestSolutionProcessor() {
-      SequentialProcessor seq = new SequentialProcessor();
-      ProgrammableOperator progOperator = new ProgrammableOperator();
-      progOperator.RemoveVariableInfo("Result");
-      progOperator.AddVariableInfo(new HeuristicLab.Core.VariableInfo("EvaluatedSolutions", "", typeof(IntData), VariableKind.In));
-      progOperator.Code = @"
-int evalSolutions = EvaluatedSolutions.Data;
-scope.AddVariable(new Variable(""EvaluatedSolutions"", new IntData(evalSolutions)));
-";
-      seq.AddSubOperator(progOperator);
-      return seq;
-    }
-
-    protected internal virtual IOperator CreateReplacement() {
-      CombinedOperator replacement = new CombinedOperator();
-      replacement.Name = "Replacement";
-      SequentialProcessor seq = new SequentialProcessor();
-      SequentialSubScopesProcessor seqScopeProc = new SequentialSubScopesProcessor();
-      SequentialProcessor selectedProc = new SequentialProcessor();
-      LeftSelector leftSelector = new LeftSelector();
-      leftSelector.GetVariableInfo("Selected").ActualName = "Elites";
-      RightReducer rightReducer = new RightReducer();
-
-      SequentialProcessor remainingProc = new SequentialProcessor();
-      RightSelector rightSelector = new RightSelector();
-      rightSelector.GetVariableInfo("Selected").ActualName = "Elites";
-      LeftReducer leftReducer = new LeftReducer();
-      MergingReducer mergingReducer = new MergingReducer();
-      Sorter sorter = new Sorter();
-      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
-      sorter.GetVariableInfo("Value").ActualName = "Quality";
-
-      seq.AddSubOperator(seqScopeProc);
-      seqScopeProc.AddSubOperator(selectedProc);
-      selectedProc.AddSubOperator(leftSelector);
-      selectedProc.AddSubOperator(rightReducer);
-
-      seqScopeProc.AddSubOperator(remainingProc);
-      remainingProc.AddSubOperator(rightSelector);
-      remainingProc.AddSubOperator(leftReducer);
-      seq.AddSubOperator(mergingReducer);
-      seq.AddSubOperator(sorter);
-      replacement.OperatorGraph.AddOperator(seq);
-      replacement.OperatorGraph.InitialOperator = seq;
-      return replacement;
-    }
-
-    protected internal virtual IOperator CreateChildCreater() {
+    protected virtual IOperator CreateChildCreater() {
       CombinedOperator childCreater = new CombinedOperator();
       childCreater.Name = "Create children";
@@ -358,8 +329,4 @@
       evaluator.Name = "Evaluator (extr.)";
       evaluator.GetVariableInfo("Operator").ActualName = "Evaluator";
-      MeanSquaredErrorEvaluator validationEvaluator = new MeanSquaredErrorEvaluator();
-      validationEvaluator.GetVariableInfo("MSE").ActualName = "ValidationQuality";
-      validationEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
-      validationEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
       Counter evalCounter = new Counter();
       evalCounter.GetVariableInfo("Value").ActualName = "EvaluatedSolutions";
@@ -382,5 +349,4 @@
       cond.AddSubOperator(manipulator);
       individualSeqProc.AddSubOperator(evaluator);
-      individualSeqProc.AddSubOperator(validationEvaluator);
       individualSeqProc.AddSubOperator(evalCounter);
       individualSeqProc.AddSubOperator(parentRefRemover);
@@ -392,50 +358,111 @@
     }
 
-    protected internal virtual IAnalyzerModel CreateGPModel(IScope bestModelScope) {
-      IAnalyzerModel model = new AnalyzerModel();
-      model.Predictor = bestModelScope.GetVariableValue<IPredictor>("Predictor", true);
-      Dataset ds = bestModelScope.GetVariableValue<Dataset>("Dataset", true);
-      model.Dataset = ds;
-      model.TargetVariable = ds.GetVariableName(bestModelScope.GetVariableValue<IntData>("TargetVariable", true).Data);
-      model.TrainingSamplesStart = bestModelScope.GetVariableValue<IntData>("TrainingSamplesStart", true).Data;
-      model.TrainingSamplesEnd = bestModelScope.GetVariableValue<IntData>("TrainingSamplesEnd", true).Data;
-      model.ValidationSamplesStart = bestModelScope.GetVariableValue<IntData>("ValidationSamplesStart", true).Data;
-      model.ValidationSamplesEnd = bestModelScope.GetVariableValue<IntData>("ValidationSamplesEnd", true).Data;
-      model.TestSamplesStart = bestModelScope.GetVariableValue<IntData>("TestSamplesStart", true).Data;
-      model.TestSamplesEnd = bestModelScope.GetVariableValue<IntData>("TestSamplesEnd", true).Data;
-
-      model.TrainingMeanSquaredError = bestModelScope.GetVariableValue<DoubleData>("TrainingMSE", false).Data;
-      model.ValidationMeanSquaredError = bestModelScope.GetVariableValue<DoubleData>("ValidationMSE", false).Data;
-      model.TestMeanSquaredError = bestModelScope.GetVariableValue<DoubleData>("TestMSE", false).Data;
-      model.TrainingCoefficientOfDetermination = bestModelScope.GetVariableValue<DoubleData>("TrainingR2", false).Data;
-      model.ValidationCoefficientOfDetermination = bestModelScope.GetVariableValue<DoubleData>("ValidationR2", false).Data;
-      model.TestCoefficientOfDetermination = bestModelScope.GetVariableValue<DoubleData>("TestR2", false).Data;
-      model.TrainingMeanAbsolutePercentageError = bestModelScope.GetVariableValue<DoubleData>("TrainingMAPE", false).Data;
-      model.ValidationMeanAbsolutePercentageError = bestModelScope.GetVariableValue<DoubleData>("ValidationMAPE", false).Data;
-      model.TestMeanAbsolutePercentageError = bestModelScope.GetVariableValue<DoubleData>("TestMAPE", false).Data;
-      model.TrainingMeanAbsolutePercentageOfRangeError = bestModelScope.GetVariableValue<DoubleData>("TrainingMAPRE", false).Data;
-      model.ValidationMeanAbsolutePercentageOfRangeError = bestModelScope.GetVariableValue<DoubleData>("ValidationMAPRE", false).Data;
-      model.TestMeanAbsolutePercentageOfRangeError = bestModelScope.GetVariableValue<DoubleData>("TestMAPRE", false).Data;
-      model.TrainingVarianceAccountedFor = bestModelScope.GetVariableValue<DoubleData>("TrainingVAF", false).Data;
-      model.ValidationVarianceAccountedFor = bestModelScope.GetVariableValue<DoubleData>("ValidationVAF", false).Data;
-      model.TestVarianceAccountedFor = bestModelScope.GetVariableValue<DoubleData>("TestVAF", false).Data;
-
-      ItemList evaluationImpacts = bestModelScope.GetVariableValue<ItemList>("VariableEvaluationImpacts", false);
-      ItemList qualityImpacts = bestModelScope.GetVariableValue<ItemList>("VariableQualityImpacts", false);
-      foreach (ItemList row in evaluationImpacts) {
-        string variableName = ((StringData)row[0]).Data;
-        double impact = ((DoubleData)row[1]).Data;
-        model.SetVariableEvaluationImpact(variableName, impact);
-        model.AddInputVariable(variableName);
-      }
-      foreach (ItemList row in qualityImpacts) {
-        string variableName = ((StringData)row[0]).Data;
-        double impact = ((DoubleData)row[1]).Data;
-        model.SetVariableQualityImpact(variableName, impact);
-        model.AddInputVariable(variableName);
-      }
-
-      return model;
-    }
+    protected virtual IOperator CreateReplacement() {
+      CombinedOperator replacement = new CombinedOperator();
+      replacement.Name = "Replacement";
+      SequentialProcessor seq = new SequentialProcessor();
+      SequentialSubScopesProcessor seqScopeProc = new SequentialSubScopesProcessor();
+      SequentialProcessor selectedProc = new SequentialProcessor();
+      LeftSelector leftSelector = new LeftSelector();
+      leftSelector.GetVariableInfo("Selected").ActualName = "Elites";
+      RightReducer rightReducer = new RightReducer();
+
+      SequentialProcessor remainingProc = new SequentialProcessor();
+      RightSelector rightSelector = new RightSelector();
+      rightSelector.GetVariableInfo("Selected").ActualName = "Elites";
+      LeftReducer leftReducer = new LeftReducer();
+      MergingReducer mergingReducer = new MergingReducer();
+      Sorter sorter = new Sorter();
+      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
+      sorter.GetVariableInfo("Value").ActualName = "Quality";
+
+      seq.AddSubOperator(seqScopeProc);
+      seqScopeProc.AddSubOperator(selectedProc);
+      selectedProc.AddSubOperator(leftSelector);
+      selectedProc.AddSubOperator(rightReducer);
+
+      seqScopeProc.AddSubOperator(remainingProc);
+      remainingProc.AddSubOperator(rightSelector);
+      remainingProc.AddSubOperator(leftReducer);
+      seq.AddSubOperator(mergingReducer);
+      seq.AddSubOperator(sorter);
+      replacement.OperatorGraph.AddOperator(seq);
+      replacement.OperatorGraph.InitialOperator = seq;
+      return replacement;
+    }
+
+    protected virtual IOperator CreateLoggingOperator() {
+      CombinedOperator loggingOperator = new CombinedOperator();
+      loggingOperator.Name = "Logging";
+      SequentialProcessor seq = new SequentialProcessor();
+
+      DataCollector collector = new DataCollector();
+      ItemList<StringData> names = collector.GetVariable("VariableNames").GetValue<ItemList<StringData>>();
+      names.Add(new StringData("BestQuality"));
+      names.Add(new StringData("AverageQuality"));
+      names.Add(new StringData("WorstQuality"));
+      LinechartInjector lineChartInjector = new LinechartInjector();
+      lineChartInjector.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
+      lineChartInjector.GetVariable("NumberOfLines").GetValue<IntData>().Data = 3;
+      QualityLogger qualityLogger = new QualityLogger();
+
+      seq.AddSubOperator(collector);
+      seq.AddSubOperator(lineChartInjector);
+      seq.AddSubOperator(qualityLogger);
+
+      loggingOperator.OperatorGraph.AddOperator(seq);
+      loggingOperator.OperatorGraph.InitialOperator = seq;
+      return loggingOperator;
+    }
+
+    protected virtual IOperator CreateGenerationStepHook() {
+      return new EmptyOperator();
+    }
+
+    protected virtual IOperator CreateTerminationCondition() {
+      CombinedOperator terminationCriterion = new CombinedOperator();
+      terminationCriterion.Name = "TerminationCondition";
+      SequentialProcessor seq = new SequentialProcessor();
+      GreaterThanComparator comparator = new GreaterThanComparator();
+      comparator.GetVariableInfo("LeftSide").ActualName = "Generations";
+      comparator.GetVariableInfo("RightSide").ActualName = "MaxGenerations";
+      comparator.GetVariableInfo("Result").ActualName = "TerminationCriterion";
+
+      seq.AddSubOperator(comparator);
+      terminationCriterion.OperatorGraph.AddOperator(seq);
+      terminationCriterion.OperatorGraph.InitialOperator = seq;
+      return terminationCriterion;
+    }
+
+    protected virtual IOperator CreateEvaluationOperator() {
+      return new EmptyOperator();
+    }
+
+    protected virtual IOperator CreateManipulationOperator() {
+      ChangeNodeTypeManipulation manipulator = new ChangeNodeTypeManipulation();
+      manipulator.Name = "Manipulator";
+      return manipulator;
+    }
+
+    protected virtual IOperator CreateCrossoverOperator() {
+      StandardCrossOver crossover = new StandardCrossOver();
+      crossover.Name = "Crossover";
+      return crossover;
+    }
+
+    protected virtual IOperator CreateSelectionOperator() {
+      TournamentSelector selector = new TournamentSelector();
+      selector.GetVariableInfo("Selected").ActualName = "Parents";
+      selector.GetVariable("GroupSize").Value = new IntData(7);
+      selector.Name = "Selector";
+      return selector;
+    }
+
+    #endregion
+
+    protected virtual IOperator CreatePostProcessingOperator() {
+      return new EmptyOperator();
+    }
+
 
     public override object Clone(IDictionary<Guid, object> clonedObjects) {
@@ -446,16 +473,16 @@
     }
 
-    protected VariableInjector GetVariableInjector() {
-      CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
-      // SequentialProcessor in GP
-      algorithm = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
-      return (VariableInjector)algorithm.SubOperators[2];
-    }
-
-    protected RandomInjector GetRandomInjector() {
-      CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
-      // SequentialProcessor in GP
-      algorithm = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
-      return (RandomInjector)algorithm.SubOperators[0];
+    protected virtual IOperator GetVariableInjector() {
+      CombinedOperator init = (CombinedOperator)GetInitializationOperator();
+      return init.OperatorGraph.InitialOperator.SubOperators[1];
+    }
+
+    protected virtual IOperator GetRandomInjector() {
+      CombinedOperator init = (CombinedOperator)GetInitializationOperator();
+      return init.OperatorGraph.InitialOperator.SubOperators[0];
+    }
+
+    protected virtual IOperator GetInitializationOperator() {
+      return algorithm.SubOperators[0];
     }
 
Index: branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/HeuristicLab.GP.Algorithms-3.2.csproj
===================================================================
--- branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/HeuristicLab.GP.Algorithms-3.2.csproj	(revision 2331)
+++ branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/HeuristicLab.GP.Algorithms-3.2.csproj	(revision 2335)
@@ -70,4 +70,5 @@
       <RequiredTargetFramework>3.5</RequiredTargetFramework>
     </Reference>
+    <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml.Linq">
@@ -83,5 +84,7 @@
     <Compile Include="AlgorithmBase.cs" />
     <Compile Include="HeuristicLabGpAlgorithmsPlugin.cs" />
-    <Compile Include="OffspringSelectionGP.cs" />
+    <Compile Include="OffspringSelectionGP.cs">
+      <SubType>Code</SubType>
+    </Compile>
     <Compile Include="OffSpringSelectionGpEditor.cs">
       <SubType>UserControl</SubType>
Index: branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/OffspringSelectionGP.cs
===================================================================
--- branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/OffspringSelectionGP.cs	(revision 2331)
+++ branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/OffspringSelectionGP.cs	(revision 2335)
@@ -31,5 +31,5 @@
 
 namespace HeuristicLab.GP.Algorithms {
-  public class OffspringSelectionGP : StandardGP {
+  public class OffspringSelectionGP : AlgorithmBase, IEditable {
     public override string Name { get { return "OffspringSelectionGP"; } }
 
@@ -52,14 +52,4 @@
       get { return GetVariableInjector().GetVariable("SuccessRatioLimit").GetValue<DoubleData>().Data; }
       set { GetVariableInjector().GetVariable("SuccessRatioLimit").GetValue<DoubleData>().Data = value; }
-    }
-
-    public override int MaxGenerations {
-      get { throw new NotSupportedException(); }
-      set { /* ignore */ }
-    }
-
-    public override int TournamentSize {
-      get { throw new NotSupportedException(); }
-      set { /* ignore */ }
     }
 
@@ -68,4 +58,5 @@
       PopulationSize = 1000;
       Parents = 20;
+      MaxGenerations = 10000; // something large to make sure we either stop because of max-evaluated soltions or selection pressure limit
       MaxEvaluatedSolutions = 5000000;
       SelectionPressureLimit = 400;
@@ -74,8 +65,6 @@
     }
 
-    protected internal override IOperator CreateGlobalInjector() {
-      VariableInjector injector = (VariableInjector)base.CreateGlobalInjector();
-      injector.RemoveVariable("TournamentSize");
-      injector.RemoveVariable("MaxGenerations");
+    protected override VariableInjector CreateGlobalInjector() {
+      VariableInjector injector = base.CreateGlobalInjector();
       injector.AddVariable(new HeuristicLab.Core.Variable("MaxEvaluatedSolutions", new IntData()));
       injector.AddVariable(new HeuristicLab.Core.Variable("ComparisonFactor", new DoubleData()));
@@ -85,5 +74,5 @@
     }
 
-    protected internal override IOperator CreateSelector() {
+    protected override IOperator CreateSelectionOperator() {
       CombinedOperator selector = new CombinedOperator();
       selector.Name = "Selector";
@@ -115,5 +104,5 @@
     }
 
-    protected internal override IOperator CreateChildCreater() {
+    protected override IOperator CreateChildCreater() {
       CombinedOperator childCreater = new CombinedOperator();
       childCreater.Name = "Create children";
@@ -150,11 +139,4 @@
       sorter.GetVariableInfo("Value").ActualName = "Quality";
 
-      UniformSequentialSubScopesProcessor validationEvaluator = new UniformSequentialSubScopesProcessor();
-      MeanSquaredErrorEvaluator validationQualityEvaluator = new MeanSquaredErrorEvaluator();
-      validationQualityEvaluator.Name = "ValidationMeanSquaredErrorEvaluator";
-      validationQualityEvaluator.GetVariableInfo("MSE").ActualName = "ValidationQuality";
-      validationQualityEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
-      validationQualityEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
-
       main.AddSubOperator(seq);
       seq.AddSubOperator(selector);
@@ -181,11 +163,5 @@
       main.AddSubOperator(seqSubScopesProc2);
       seqSubScopesProc2.AddSubOperator(emptyOp);
-
-      SequentialProcessor newGenProc = new SequentialProcessor();
-      newGenProc.AddSubOperator(sorter);
-      newGenProc.AddSubOperator(validationEvaluator);
-      seqSubScopesProc2.AddSubOperator(newGenProc);
-
-      validationEvaluator.AddSubOperator(validationQualityEvaluator);
+      seqSubScopesProc2.AddSubOperator(sorter);
 
       childCreater.OperatorGraph.AddOperator(main);
@@ -194,33 +170,40 @@
     }
 
-    protected internal override IOperator CreateLoopCondition(IOperator loop) {
-      SequentialProcessor seq = new SequentialProcessor();
-      seq.Name = "Loop Condition";
-      LessThanComparator generationsComparator = new LessThanComparator();
-      generationsComparator.GetVariableInfo("LeftSide").ActualName = "EvaluatedSolutions";
-      generationsComparator.GetVariableInfo("RightSide").ActualName = "MaxEvaluatedSolutions";
-      generationsComparator.GetVariableInfo("Result").ActualName = "EvaluatedSolutionsCondition";
-
-      LessThanComparator selPresComparator = new LessThanComparator();
+    protected override IOperator CreateTerminationCondition() {
+      CombinedOperator terminationCritertion = new CombinedOperator();
+      terminationCritertion.Name = "TerminationCondition";
+      GreaterThanComparator selPresComparator = new GreaterThanComparator();
       selPresComparator.GetVariableInfo("LeftSide").ActualName = "SelectionPressure";
       selPresComparator.GetVariableInfo("RightSide").ActualName = "SelectionPressureLimit";
-      selPresComparator.GetVariableInfo("Result").ActualName = "SelectionPressureCondition";
-
-      ConditionalBranch generationsCond = new ConditionalBranch();
-      generationsCond.GetVariableInfo("Condition").ActualName = "EvaluatedSolutionsCondition";
-
-      ConditionalBranch selPresCond = new ConditionalBranch();
-      selPresCond.GetVariableInfo("Condition").ActualName = "SelectionPressureCondition";
-
-      seq.AddSubOperator(generationsComparator);
-      seq.AddSubOperator(selPresComparator);
-      seq.AddSubOperator(generationsCond);
-      generationsCond.AddSubOperator(selPresCond);
-      selPresCond.AddSubOperator(loop);
+      selPresComparator.GetVariableInfo("Result").ActualName = "TerminationCriterion";
+
+      IOperator baseAndSelPresTerminationCriterion = CombineTerminationCriterions(base.CreateTerminationCondition(), selPresComparator);
+
+      GreaterThanComparator evalSolutionsComparer = new GreaterThanComparator();
+      evalSolutionsComparer.GetVariableInfo("LeftSide").ActualName = "EvaluatedSolutions";
+      evalSolutionsComparer.GetVariableInfo("RightSide").ActualName = "MaxEvaluatedSolutions";
+      evalSolutionsComparer.GetVariableInfo("Result").ActualName = "TerminationCriterion";
+
+      IOperator combinedTerminationCritertion = CombineTerminationCriterions(baseAndSelPresTerminationCriterion, evalSolutionsComparer);
+
+      terminationCritertion.OperatorGraph.AddOperator(combinedTerminationCritertion);
+      terminationCritertion.OperatorGraph.InitialOperator = combinedTerminationCritertion;
+      return terminationCritertion;
+    }
+
+    private IOperator CombineTerminationCriterions(IOperator criterion1, IOperator criterion2) {
+      ConditionalBranch branch = new ConditionalBranch();
+      branch.GetVariableInfo("Condition").ActualName = "TerminationCriterion";
+      branch.AddSubOperator(new EmptyOperator());
+      branch.AddSubOperator(criterion2);
+
+      SequentialProcessor seq = new SequentialProcessor();
+      seq.AddSubOperator(criterion1);
+      seq.AddSubOperator(branch);
 
       return seq;
     }
 
-    protected internal override IOperator CreateLoggingOperator() {
+    protected override IOperator CreateLoggingOperator() {
       CombinedOperator loggingOperator = new CombinedOperator();
       loggingOperator.Name = "Logging";
@@ -232,18 +215,9 @@
       names.Add(new StringData("AverageQuality"));
       names.Add(new StringData("WorstQuality"));
-      names.Add(new StringData("BestValidationQuality"));
-      names.Add(new StringData("AverageValidationQuality"));
-      names.Add(new StringData("WorstValidationQuality"));
       names.Add(new StringData("EvaluatedSolutions"));
       names.Add(new StringData("SelectionPressure"));
       QualityLogger qualityLogger = new QualityLogger();
-      QualityLogger validationQualityLogger = new QualityLogger();
-      validationQualityLogger.Name = "ValidationQualityLogger";
-      validationQualityLogger.GetVariableInfo("Quality").ActualName = "ValidationQuality";
-      validationQualityLogger.GetVariableInfo("QualityLog").ActualName = "ValidationQualityLog";
-
       seq.AddSubOperator(collector);
       seq.AddSubOperator(qualityLogger);
-      seq.AddSubOperator(validationQualityLogger);
 
       loggingOperator.OperatorGraph.AddOperator(seq);
@@ -252,6 +226,5 @@
     }
 
-
-    public override IEditor CreateEditor() {
+    public virtual IEditor CreateEditor() {
       return new OffspringSelectionGpEditor(this);
     }
Index: branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/StandardGP.cs
===================================================================
--- branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/StandardGP.cs	(revision 2331)
+++ branches/gp-algorithms-refactoring-#720/sources/HeuristicLab.GP.Algorithms/3.2/StandardGP.cs	(revision 2335)
@@ -31,20 +31,4 @@
 
     public override string Name { get { return "StandardGP"; } }
-
-    public override int TargetVariable {
-      get { return ProblemInjector.GetVariableValue<IntData>("TargetVariable", null, false).Data; }
-      set { ProblemInjector.GetVariableValue<IntData>("TargetVariable", null, false).Data = value; }
-    }
-
-    public override Dataset Dataset {
-      get { return ProblemInjector.GetVariableValue<Dataset>("Dataset", null, false); }
-      set { ProblemInjector.GetVariable("Dataset").Value = value; }
-    }
-
-    public virtual int MaxGenerations {
-      get { return GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("MaxGenerations").GetValue<IntData>().Data = value; }
-    }
-
     public virtual int TournamentSize {
       get { return GetVariableInjector().GetVariable("TournamentSize").GetValue<IntData>().Data; }
@@ -62,19 +46,4 @@
     }
 
-    public int MinInitialTreeSize {
-      get { return GetVariableInjector().GetVariable("MinInitialTreeSize").GetValue<IntData>().Data; }
-      set { GetVariableInjector().GetVariable("MinInitialTreeSize").GetValue<IntData>().Data = value; }
-    }
-
-    public override int MaxTreeSize {
-      get {
-        return base.MaxTreeSize;
-      }
-      set {
-        base.MaxTreeSize = value;
-        MinInitialTreeSize = value / 2;
-      }
-    }
-
     public override int PopulationSize {
       get {
@@ -84,13 +53,4 @@
         base.PopulationSize = value;
         Parents = 2 * value;
-      }
-    }
-
-    public override IOperator ProblemInjector {
-      get { return base.ProblemInjector.SubOperators[0]; }
-      set {
-        value.Name = "ProblemInjector";
-        base.ProblemInjector.RemoveSubOperator(0);
-        base.ProblemInjector.AddSubOperator(value, 0);
       }
     }
@@ -107,24 +67,8 @@
       FullTreeShakingFactor = 0.1;
       OnePointShakingFactor = 1.0;
-      UseEstimatedTargetValue = false;
       SetSeedRandomly = true;
     }
 
-    protected internal override IOperator CreateProblemInjector() {
-      SequentialProcessor seq = new SequentialProcessor();
-      var probInject = new ProblemInjector();
-      probInject.GetVariableInfo("MaxNumberOfTrainingSamples").Local = true;
-      probInject.AddVariable(new HeuristicLab.Core.Variable("MaxNumberOfTrainingSamples", new IntData(5000)));
-
-      var shuffler = new DatasetShuffler();
-      shuffler.GetVariableInfo("ShuffleStart").ActualName = "TrainingSamplesStart";
-      shuffler.GetVariableInfo("ShuffleEnd").ActualName = "TrainingSamplesEnd";
-
-      seq.AddSubOperator(probInject);
-      seq.AddSubOperator(shuffler);
-      return seq;
-    }
-
-    protected internal override IOperator CreateSelector() {
+    protected override IOperator CreateSelectionOperator() {
       TournamentSelector selector = new TournamentSelector();
       selector.Name = "Selector";
@@ -136,35 +80,13 @@
     }
 
-    protected internal override IOperator CreateGlobalInjector() {
-      VariableInjector globalInjector = (VariableInjector)base.CreateGlobalInjector();
+    protected override VariableInjector CreateGlobalInjector() {
+      VariableInjector globalInjector = base.CreateGlobalInjector();
       globalInjector.AddVariable(new HeuristicLab.Core.Variable("TournamentSize", new IntData()));
-      globalInjector.AddVariable(new HeuristicLab.Core.Variable("MaxGenerations", new IntData()));
       globalInjector.AddVariable(new HeuristicLab.Core.Variable("FullTreeShakingFactor", new DoubleData()));
       globalInjector.AddVariable(new HeuristicLab.Core.Variable("OnePointShakingFactor", new DoubleData()));
-      globalInjector.AddVariable(new HeuristicLab.Core.Variable("MinInitialTreeSize", new IntData()));
       return globalInjector;
     }
 
-    protected internal override IOperator CreateCrossover() {
-      StandardCrossOver crossover = new StandardCrossOver();
-      crossover.Name = "Crossover";
-      return crossover;
-    }
-
-    protected internal override IOperator CreateTreeCreator() {
-      ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
-      treeCreator.Name = "Tree generator";
-      treeCreator.GetVariableInfo("MinTreeSize").ActualName = "MinInitialTreeSize";
-      return treeCreator;
-    }
-
-    protected internal override IOperator CreateFunctionLibraryInjector() {
-      FunctionLibraryInjector funLibInjector = new FunctionLibraryInjector();
-      funLibInjector.GetVariableValue<BoolData>("Xor", null, false).Data = false;
-      funLibInjector.GetVariableValue<BoolData>("Average", null, false).Data = false;
-      return funLibInjector;
-    }
-
-    protected internal override IOperator CreateManipulator() {
+    protected override IOperator CreateManipulationOperator() {
       CombinedOperator manipulator = new CombinedOperator();
       manipulator.Name = "Manipulator";
@@ -200,36 +122,4 @@
     }
 
-    protected internal override IOperator CreateLoggingOperator() {
-      CombinedOperator loggingOperator = new CombinedOperator();
-      loggingOperator.Name = "Logging";
-      SequentialProcessor seq = new SequentialProcessor();
-
-      DataCollector collector = new DataCollector();
-      ItemList<StringData> names = collector.GetVariable("VariableNames").GetValue<ItemList<StringData>>();
-      names.Add(new StringData("BestQuality"));
-      names.Add(new StringData("AverageQuality"));
-      names.Add(new StringData("WorstQuality"));
-      names.Add(new StringData("BestValidationQuality"));
-      names.Add(new StringData("AverageValidationQuality"));
-      names.Add(new StringData("WorstValidationQuality"));
-      LinechartInjector lineChartInjector = new LinechartInjector();
-      lineChartInjector.GetVariableInfo("Linechart").ActualName = "Quality Linechart";
-      lineChartInjector.GetVariable("NumberOfLines").GetValue<IntData>().Data = 6;
-      QualityLogger qualityLogger = new QualityLogger();
-      QualityLogger validationQualityLogger = new QualityLogger();
-      validationQualityLogger.Name = "ValidationQualityLogger";
-      validationQualityLogger.GetVariableInfo("Quality").ActualName = "ValidationQuality";
-      validationQualityLogger.GetVariableInfo("QualityLog").ActualName = "ValidationQualityLog";
-
-      seq.AddSubOperator(collector);
-      seq.AddSubOperator(lineChartInjector);
-      seq.AddSubOperator(qualityLogger);
-      seq.AddSubOperator(validationQualityLogger);
-
-      loggingOperator.OperatorGraph.AddOperator(seq);
-      loggingOperator.OperatorGraph.InitialOperator = seq;
-      return loggingOperator;
-    }
-
     public virtual IEditor CreateEditor() {
       return new StandardGpEditor(this);
