Index: branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/AlgorithmBase.cs
===================================================================
--- branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/AlgorithmBase.cs	(revision 1230)
+++ branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/AlgorithmBase.cs	(revision 1230)
@@ -0,0 +1,425 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2008 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.Core;
+using System.Xml;
+using System.Diagnostics;
+using HeuristicLab.DataAnalysis;
+using HeuristicLab.Operators;
+using HeuristicLab.Random;
+using HeuristicLab.Selection;
+using HeuristicLab.Logging;
+using HeuristicLab.Data;
+using HeuristicLab.Operators.Programmable;
+
+namespace HeuristicLab.GP.StructureIdentification {
+  public abstract class AlgorithmBase : ItemBase, IEditable {
+    private DoubleData mutationRate = new DoubleData();
+    public double MutationRate {
+      get { return mutationRate.Data; }
+      set { mutationRate.Data = value; }
+    }
+    private IntData populationSize = new IntData();
+    public int PopulationSize {
+      get { return populationSize.Data; }
+      set {
+        populationSize.Data = value;
+      }
+    }
+
+    private BoolData setSeedRandomly = new BoolData();
+    public bool SetSeedRandomly {
+      get { return setSeedRandomly.Data; }
+      set { setSeedRandomly.Data = value; }
+    }
+
+    private IntData seed = new IntData();
+    public int Seed {
+      get { return seed.Data; }
+      set { seed.Data = value; }
+    }
+
+    public IOperator ProblemInjector {
+      get { return algorithm.SubOperators[0]; }
+      set {
+        value.Name = "ProblemInjector";
+        algorithm.RemoveSubOperator(0);
+        algorithm.AddSubOperator(value, 0);
+      }
+    }
+
+    private IntData elites = new IntData();
+    public int Elites {
+      get { return elites.Data; }
+      set { elites.Data = value; }
+    }
+
+    private int maxTreeSize = 50;
+    public int MaxTreeSize {
+      get { return maxTreeSize; }
+      set { maxTreeSize = value; }
+    }
+
+    private int maxTreeHeight = 8;
+    public int MaxTreeHeight {
+      get { return maxTreeHeight; }
+      set { maxTreeHeight = value; }
+    }
+
+    private double punishmentFactor = 10.0;
+    private bool useEstimatedTargetValue = false;
+    private double fullTreeShakingFactor = 0.1;
+    private double onepointShakingFactor = 1.0;
+    private IOperator algorithm;
+
+    private SequentialEngine.SequentialEngine engine;
+    public IEngine Engine {
+      get { return engine; }
+    }
+
+    public AlgorithmBase() {
+      PopulationSize = 10000;
+      MutationRate = 0.15;
+      Elites = 1;
+      MaxTreeSize = 100;
+      MaxTreeHeight = 10;
+      engine = new SequentialEngine.SequentialEngine();
+      CombinedOperator algo = CreateAlgorithm();
+      engine.OperatorGraph.AddOperator(algo);
+      engine.OperatorGraph.InitialOperator = algo;
+    }
+
+    virtual CombinedOperator CreateAlgorithm() {
+      CombinedOperator algo = new CombinedOperator();
+      algo.Name = "GP";
+      SequentialProcessor seq = new SequentialProcessor();
+      EmptyOperator problemInjectorPlaceholder = new EmptyOperator();
+
+      RandomInjector randomInjector = new RandomInjector();
+      randomInjector.GetVariable("SetSeedRandomly").Value = setSeedRandomly;
+      randomInjector.GetVariable("Seed").Value = seed;
+      randomInjector.Name = "Random Injector";
+
+      IOperator globalInjector = CreateGlobalInjector();
+      IOperator initialization = CreateInitialization();
+      IOperator funLibInjector = CreateFunctionLibraryInjector(); 
+      IOperator mainLoop = CreateMainLoop();
+      mainLoop.Name = "Main loop";
+
+      IOperator treeCreator = CreateTreeCreator();
+      
+      MeanSquaredErrorEvaluator evaluator = new MeanSquaredErrorEvaluator();
+      evaluator.GetVariableInfo("MSE").ActualName = "Quality";
+      evaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
+      evaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
+      evaluator.Name = "Evaluator";
+      
+      IOperator crossover = CreateCrossover();
+      IOperator manipulator = CreateManipulator();
+
+      IOperator selector = CreateSelector();
+      LeftReducer cleanUp = new LeftReducer();
+
+      seq.AddSubOperator(problemInjectorPlaceholder);
+      seq.AddSubOperator(randomInjector);
+      seq.AddSubOperator(globalInjector);
+      seq.AddSubOperator(funLibInjector);
+      seq.AddSubOperator(initialization);
+      seq.AddSubOperator(mainLoop);
+      seq.AddSubOperator(cleanUp);
+
+      initialization.AddSubOperator(treeCreator);
+      initialization.AddSubOperator(evaluator);
+
+      mainLoop.AddSubOperator(selector);
+      mainLoop.AddSubOperator(crossover);
+      mainLoop.AddSubOperator(manipulator);
+      mainLoop.AddSubOperator(evaluator);
+      algo.OperatorGraph.AddOperator(seq);
+      algo.OperatorGraph.InitialOperator = seq;
+      this.algorithm = seq;
+      return algo;
+    }
+
+    internal abstract IOperator CreateSelector();
+
+    abstract IOperator CreateCrossover();
+
+    abstract IOperator CreateTreeCreator();
+
+    abstract IOperator CreateFunctionLibraryInjector();
+
+    virtual IOperator 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("MutationRate", mutationRate));
+      injector.AddVariable(new HeuristicLab.Core.Variable("PopulationSize", populationSize));
+      injector.AddVariable(new HeuristicLab.Core.Variable("Elites", elites));
+      injector.AddVariable(new HeuristicLab.Core.Variable("Maximization", new BoolData(false)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new IntData(maxTreeHeight)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new IntData(maxTreeSize)));
+      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("PunishmentFactor", new DoubleData(punishmentFactor)));
+      injector.AddVariable(new HeuristicLab.Core.Variable("UseEstimatedTargetValue", new BoolData(useEstimatedTargetValue)));
+      return injector;
+    }
+
+    abstract IOperator CreateManipulator();
+
+    virtual IOperator CreateInitialization() {
+      CombinedOperator init = new CombinedOperator();
+      init.Name = "Initialization";
+      SequentialProcessor seq = new SequentialProcessor();
+      SubScopesCreater subScopesCreater = new SubScopesCreater();
+      subScopesCreater.GetVariableInfo("SubScopes").ActualName = "PopulationSize";
+      UniformSequentialSubScopesProcessor subScopesProc = new UniformSequentialSubScopesProcessor();
+      SequentialProcessor individualSeq = new SequentialProcessor();
+      OperatorExtractor treeCreater = new OperatorExtractor();
+      treeCreater.Name = "Tree generator (extr.)";
+      treeCreater.GetVariableInfo("Operator").ActualName = "Tree 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";
+      Sorter sorter = new Sorter();
+      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
+      sorter.GetVariableInfo("Value").ActualName = "Quality";
+
+      seq.AddSubOperator(subScopesCreater);
+      seq.AddSubOperator(subScopesProc);
+      seq.AddSubOperator(sorter);
+
+      subScopesProc.AddSubOperator(individualSeq);
+      individualSeq.AddSubOperator(treeCreater);
+      individualSeq.AddSubOperator(evaluator);
+      individualSeq.AddSubOperator(validationEvaluator);
+      individualSeq.AddSubOperator(evalCounter);
+
+      init.OperatorGraph.AddOperator(seq);
+      init.OperatorGraph.InitialOperator = seq;
+      return init;
+    }
+
+    virtual IOperator CreateMainLoop() {
+      CombinedOperator main = new CombinedOperator();
+      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 = "ValidationQualityCalculator";
+      validationQualityCalculator.GetVariableInfo("BestQuality").ActualName = "BestValidationQuality";
+      validationQualityCalculator.GetVariableInfo("AverageQuality").ActualName = "AverageValidationQuality";
+      validationQualityCalculator.GetVariableInfo("WorstQuality").ActualName = "WorstValidationQuality";
+      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();
+      validationQualityCalculator.Name = "ValidationQualityLogger";
+      validationQualityLogger.GetVariableInfo("Quality").ActualName = "ValidationQuality";
+      validationQualityLogger.GetVariableInfo("QualityLog").ActualName = "ValidationQualityLog";
+      Counter counter = new Counter();
+      counter.GetVariableInfo("Value").ActualName = "Generations";
+      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(childCreater);
+      seq.AddSubOperator(replacement);
+      seq.AddSubOperator(solutionStorer);
+      seq.AddSubOperator(qualityCalculator);
+      seq.AddSubOperator(validationQualityCalculator);
+      seq.AddSubOperator(collector);
+      seq.AddSubOperator(lineChartInjector);
+      seq.AddSubOperator(qualityLogger);
+      seq.AddSubOperator(validationQualityLogger);
+      seq.AddSubOperator(counter);
+      seq.AddSubOperator(comparator);
+      seq.AddSubOperator(cond);
+      cond.AddSubOperator(seq);
+
+      main.OperatorGraph.AddOperator(seq);
+      main.OperatorGraph.InitialOperator = seq;
+      return main;
+    }
+
+    virtual IOperator CreateBestSolutionProcessor() {
+      return new EmptyOperator();
+    }
+
+    private 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;
+    }
+
+    private virtual IOperator CreateChildCreater() {
+      CombinedOperator childCreater = new CombinedOperator();
+      childCreater.Name = "Create children";
+      SequentialProcessor seq = new SequentialProcessor();
+      OperatorExtractor selector = new OperatorExtractor();
+      selector.Name = "Selector (extr.)";
+      selector.GetVariableInfo("Operator").ActualName = "Selector";
+      SequentialSubScopesProcessor seqScopesProc = new SequentialSubScopesProcessor();
+      EmptyOperator emptyOpt = new EmptyOperator();
+      SequentialProcessor selectedProc = new SequentialProcessor();
+      OperatorExtractor crossover = new OperatorExtractor();
+      crossover.Name = "Crossover (extr.)";
+      crossover.GetVariableInfo("Operator").ActualName = "Crossover";
+      UniformSequentialSubScopesProcessor individualProc = new UniformSequentialSubScopesProcessor();
+      SequentialProcessor individualSeqProc = new SequentialProcessor();
+      StochasticBranch cond = new StochasticBranch();
+      cond.GetVariableInfo("Probability").ActualName = "MutationRate";
+      OperatorExtractor manipulator = new OperatorExtractor();
+      manipulator.Name = "Manipulator (extr.)";
+      manipulator.GetVariableInfo("Operator").ActualName = "Manipulator";
+      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";
+
+      Sorter sorter = new Sorter();
+      sorter.GetVariableInfo("Descending").ActualName = "Maximization";
+      sorter.GetVariableInfo("Value").ActualName = "Quality";
+
+
+      seq.AddSubOperator(selector);
+      seq.AddSubOperator(seqScopesProc);
+      seqScopesProc.AddSubOperator(emptyOpt);
+      seqScopesProc.AddSubOperator(selectedProc);
+      selectedProc.AddSubOperator(crossover);
+      selectedProc.AddSubOperator(individualProc);
+      individualProc.AddSubOperator(individualSeqProc);
+      individualSeqProc.AddSubOperator(cond);
+      cond.AddSubOperator(manipulator);
+      individualSeqProc.AddSubOperator(evaluator);
+      individualSeqProc.AddSubOperator(validationEvaluator);
+      individualSeqProc.AddSubOperator(evalCounter);
+      selectedProc.AddSubOperator(sorter);
+
+      childCreater.OperatorGraph.AddOperator(seq);
+      childCreater.OperatorGraph.InitialOperator = seq;
+      return childCreater;
+    }
+
+    public override object Clone(IDictionary<Guid, object> clonedObjects) {
+      AlgorithmBase clone = (AlgorithmBase)base.Clone(clonedObjects);
+      clonedObjects.Add(Guid, clone);
+      clone.engine = (SequentialEngine.SequentialEngine)Auxiliary.Clone(Engine, clonedObjects);
+      return clone;
+    }
+
+    #region SetReferences Method
+    private void SetReferences() {
+      // SGA
+      CombinedOperator co1 = (CombinedOperator)Engine.OperatorGraph.InitialOperator;
+      // SequentialProcessor in SGA
+      algorithm = (SequentialProcessor)co1.OperatorGraph.InitialOperator;
+      // RandomInjector
+      RandomInjector ri = (RandomInjector)algorithm.SubOperators[1];
+      setSeedRandomly = ri.GetVariable("SetSeedRandomly").GetValue<BoolData>();
+      seed = ri.GetVariable("Seed").GetValue<IntData>();
+      // VariableInjector
+      VariableInjector vi = (VariableInjector)algorithm.SubOperators[2];
+      populationSize = vi.GetVariable("PopulationSize").GetValue<IntData>();
+      parents = vi.GetVariable("Parents").GetValue<IntData>();
+      maxGenerations = vi.GetVariable("MaxGenerations").GetValue<IntData>();
+      mutationRate = vi.GetVariable("MutationRate").GetValue<DoubleData>();
+      elites = vi.GetVariable("Elites").GetValue<IntData>();
+    }
+    #endregion
+
+    #region Persistence Methods
+    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) {
+      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
+      node.AppendChild(PersistenceManager.Persist("Engine", Engine, document, persistedObjects));
+      return node;
+    }
+    public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) {
+      base.Populate(node, restoredObjects);
+      engine = (SequentialEngine.SequentialEngine)PersistenceManager.Restore(node.SelectSingleNode("Engine"), restoredObjects);
+      SetReferences();
+    }
+    #endregion
+  }
+}
Index: branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj
===================================================================
--- branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj	(revision 1226)
+++ branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/HeuristicLab.GP.StructureIdentification.csproj	(revision 1230)
@@ -71,4 +71,5 @@
     <Compile Include="BakedTreeEvaluator.cs" />
     <Compile Include="Constant.cs" />
+    <Compile Include="AlgorithmBase.cs" />
     <Compile Include="FunctionLibraryInjector.cs" />
     <Compile Include="OffspringSelectionGP.cs" />
Index: branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/StandardGP.cs
===================================================================
--- branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/StandardGP.cs	(revision 1226)
+++ branches/CEDMA-Refactoring-Ticket419/HeuristicLab.GP.StructureIdentification/StandardGP.cs	(revision 1230)
@@ -36,5 +36,6 @@
 
 namespace HeuristicLab.GP.StructureIdentification {
-  public class StandardGP : ItemBase, IEditable {
+  public class StandardGP : AlgorithmBase {
+
     private IntData maxGenerations = new IntData();
     public int MaxGenerations {
@@ -48,69 +49,6 @@
       set { tournamentSize.Data = value; }
     }
-    private DoubleData mutationRate = new DoubleData();
-    public double MutationRate {
-      get { return mutationRate.Data; }
-      set { mutationRate.Data = value; }
-    }
-    private IntData parents = new IntData();
-    private IntData populationSize = new IntData();
-    public int PopulationSize {
-      get { return populationSize.Data; }
-      set {
-        populationSize.Data = value;
-        parents.Data = value * 2;
-      }
-    }
-
-    private BoolData setSeedRandomly = new BoolData();
-    public bool SetSeedRandomly {
-      get { return setSeedRandomly.Data; }
-      set { setSeedRandomly.Data = value; }
-    }
-
-    private IntData seed = new IntData();
-    public int Seed {
-      get { return seed.Data; }
-      set { seed.Data = value; }
-    }
-
-    public IOperator ProblemInjector {
-      get { return algorithm.SubOperators[0]; }
-      set {
-        value.Name = "ProblemInjector";
-        algorithm.RemoveSubOperator(0);
-        algorithm.AddSubOperator(value, 0);
-      }
-    }
-
-    private IntData elites = new IntData();
-    public int Elites {
-      get { return elites.Data; }
-      set { elites.Data = value; }
-    }
-
-    private int maxTreeSize = 50;
-    public int MaxTreeSize {
-      get { return maxTreeSize; }
-      set { maxTreeSize = value; }
-    }
-
-    private int maxTreeHeight = 8;
-    public int MaxTreeHeight {
-      get { return maxTreeHeight; }
-      set { maxTreeHeight = value; }
-    }
-    private double punishmentFactor = 10.0;
-    private bool useEstimatedTargetValue = false;
-    private double fullTreeShakingFactor = 0.1;
-    private double onepointShakingFactor = 1.0;
-    private IOperator algorithm;
-
-    private SequentialEngine.SequentialEngine engine;
-    public IEngine Engine {
-      get { return engine; }
-    }
-
-    public StandardGP() {
+
+    public StandardGP() : base() {
       PopulationSize = 10000;
       MaxGenerations = 100;
@@ -121,40 +59,10 @@
       MaxTreeHeight = 10;
       engine = new SequentialEngine.SequentialEngine();
-      CombinedOperator algo = CreateAlgorithm();
+      IOperator algo = CreateAlgorithm();
       engine.OperatorGraph.AddOperator(algo);
       engine.OperatorGraph.InitialOperator = algo;
     }
 
-    private CombinedOperator CreateAlgorithm() {
-      CombinedOperator algo = new CombinedOperator();
-      algo.Name = "StandardGP";
-      SequentialProcessor seq = new SequentialProcessor();
-      EmptyOperator problemInjectorPlaceholder = new EmptyOperator();
-      RandomInjector randomInjector = new RandomInjector();
-      randomInjector.GetVariable("SetSeedRandomly").Value = setSeedRandomly;
-      randomInjector.GetVariable("Seed").Value = seed;
-      randomInjector.Name = "Random Injector";
-      VariableInjector globalInjector = CreateGlobalInjector();
-      CombinedOperator initialization = CreateInitialization();
-      initialization.Name = "Initialization";
-      FunctionLibraryInjector funLibInjector = new FunctionLibraryInjector();
-      CombinedOperator mainLoop = CreateMainLoop();
-      mainLoop.Name = "Main loop";
-
-      ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
-      treeCreator.Name = "Tree generator";
-      treeCreator.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
-      treeCreator.GetVariableInfo("MinTreeSize").Local = true;
-      treeCreator.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new IntData(3)));
-      MeanSquaredErrorEvaluator evaluator = new MeanSquaredErrorEvaluator();
-      evaluator.GetVariableInfo("MSE").ActualName = "Quality";
-      evaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
-      evaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
-      evaluator.Name = "Evaluator";
-      StandardCrossOver crossover = new StandardCrossOver();
-      crossover.Name = "Crossover";
-      crossover.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
-      CombinedOperator manipulator = CreateManipulator();
-      manipulator.Name = "Manipulator";
+    override IOperator CreateSelector()  {
       TournamentSelector selector = new TournamentSelector();
       selector.Name = "Selector";
@@ -163,49 +71,31 @@
       selector.RemoveVariable("GroupSize");
       selector.GetVariableInfo("GroupSize").ActualName = "TournamentSize";
-      LeftReducer cleanUp = new LeftReducer();
-
-      seq.AddSubOperator(problemInjectorPlaceholder);
-      seq.AddSubOperator(randomInjector);
-      seq.AddSubOperator(globalInjector);
-      seq.AddSubOperator(funLibInjector);
-      seq.AddSubOperator(initialization);
-      seq.AddSubOperator(mainLoop);
-      seq.AddSubOperator(cleanUp);
-
-      initialization.AddSubOperator(treeCreator);
-      initialization.AddSubOperator(evaluator);
-
-      mainLoop.AddSubOperator(selector);
-      mainLoop.AddSubOperator(crossover);
-      mainLoop.AddSubOperator(manipulator);
-      mainLoop.AddSubOperator(evaluator);
-      algo.OperatorGraph.AddOperator(seq);
-      algo.OperatorGraph.InitialOperator = seq;
-      this.algorithm = seq;
-      return algo;
-    }
-
-    private 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", maxGenerations));
-      injector.AddVariable(new HeuristicLab.Core.Variable("MutationRate", mutationRate));
-      injector.AddVariable(new HeuristicLab.Core.Variable("PopulationSize", populationSize));
-      injector.AddVariable(new HeuristicLab.Core.Variable("Parents", parents));
-      injector.AddVariable(new HeuristicLab.Core.Variable("Elites", elites));
-      injector.AddVariable(new HeuristicLab.Core.Variable("TournamentSize", tournamentSize));
-      injector.AddVariable(new HeuristicLab.Core.Variable("Maximization", new BoolData(false)));
-      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeHeight", new IntData(maxTreeHeight)));
-      injector.AddVariable(new HeuristicLab.Core.Variable("MaxTreeSize", new IntData(maxTreeSize)));
-      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("PunishmentFactor", new DoubleData(punishmentFactor)));
-      injector.AddVariable(new HeuristicLab.Core.Variable("UseEstimatedTargetValue", new BoolData(useEstimatedTargetValue)));
-      return injector;
-    }
-
-    private CombinedOperator CreateManipulator() {
+      return selector;
+    }
+
+
+    override IOperator CreateCrossover() {
+      StandardCrossOver crossover = new StandardCrossOver();
+      crossover.Name = "Crossover";
+      crossover.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
+      return crossover;
+    }
+
+    override IOperator CreateTreeCreator() {
+      ProbabilisticTreeCreator treeCreator = new ProbabilisticTreeCreator();
+      treeCreator.Name = "Tree generator";
+      treeCreator.GetVariableInfo("OperatorLibrary").ActualName = "FunctionLibrary";
+      treeCreator.GetVariableInfo("MinTreeSize").Local = true;
+      treeCreator.AddVariable(new HeuristicLab.Core.Variable("MinTreeSize", new IntData(3)));
+      return treeCreator;
+    }
+
+    override IOperator CreateFunctionLibraryInjector() {
+      return new FunctionLibraryInjector();
+    }
+
+    override IOperator CreateManipulator()  {
       CombinedOperator manipulator = new CombinedOperator();
+      manipulator.Name = "Manipulator";
       StochasticMultiBranch multibranch = new StochasticMultiBranch();
       FullTreeShaker fullTreeShaker = new FullTreeShaker();
@@ -245,4 +135,29 @@
       manipulator.OperatorGraph.InitialOperator = multibranch;
       return manipulator;
+    }
+
+    override IOperator CreateBestSolutionProcessor() {
+      SequentialProcessor bestSolutionProcessor = new SequentialProcessor();
+      MeanAbsolutePercentageErrorEvaluator trainingMapeEvaluator = new MeanAbsolutePercentageErrorEvaluator();
+      trainingMapeEvaluator.Name = "TrainingMapeEvaluator";
+      trainingMapeEvaluator.GetVariableInfo("MAPE").ActualName = "TrainingMAPE";
+      trainingMapeEvaluator.GetVariableInfo("SamplesStart").ActualName = "TrainingSamplesStart";
+      trainingMapeEvaluator.GetVariableInfo("SamplesEnd").ActualName = "TrainingSamplesEnd";
+      MeanAbsolutePercentageErrorEvaluator validationMapeEvaluator = new MeanAbsolutePercentageErrorEvaluator();
+      validationMapeEvaluator.Name = "ValidationMapeEvaluator";
+      validationMapeEvaluator.GetVariableInfo("MAPE").ActualName = "ValidationMAPE";
+      validationMapeEvaluator.GetVariableInfo("SamplesStart").ActualName = "ValidationSamplesStart";
+      validationMapeEvaluator.GetVariableInfo("SamplesEnd").ActualName = "ValidationSamplesEnd";
+      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)));
+";
+      bestSolutionProcessor.AddSubOperator(trainingMapeEvaluator);
+      bestSolutionProcessor.AddSubOperator(validationMapeEvaluator);
+      bestSolutionProcessor.AddSubOperator(progOperator);
+      return bestSolutionProcessor;
     }
 
